In Type member support in LINQ-to-Entities? I was attempting to declare a class property to be queried in LINQ which ran into some issues. Here I will lay out the code insi
The issues you're coming across are common when you couple your database objects to your domain objects. It's for this exact reason that it's good to have a separate set of classes that represent your domain and a separate set of classes that represent your database and are used for database CRUD. Overlap in properties is to be expected, but this approach offers more control of your application and decouples your database from your business logic.
The idea that a quiz is closed belongs to your domain (the business logic). Your DAL (data access layer) should be responsible for joining all the necessary tables so that when you return a Quiz, all the information needed to determine whether or not it's closed is available. Your domain/service/business layer should then create the domain object with the IsClosed
property properly populated so that in your UI layer (MVC) you can easily access it.
I see that you're access the database context directly, I'd warn against that and encourage you to look into using DI/IoC framework (Ninject is great), however, I'm going to access the database context directly also
Use this class in your views/controllers:
public class QuizDomainObject
{
public int Id {get; set;}
public bool IsClosed {get; set;}
// all other properties
}
Controller:
public class QuizController : Controller
{
public ActionResult View(int id)
{
// using a DI/IoC container is the
// preferred method instead of
// manually creating a service
var quizService = new QuizService();
QuizDomainObject quiz = quizService.GetQuiz(id);
return View(quiz);
}
}
Service/business layer:
public class QuizService
{
public QuizDomainObject GetQuiz(int id)
{
// using a DI/IoC container is the
// preferred method instead of
// access the datacontext directly
using (EFContainer db = new EFContainer())
{
Dictionary<string, int> max = db.Registry
.Where(x => x.Domain == "Quiz")
.ToDictionary(x => x.Key, x => Convert.ToInt32(x.Value));
var quiz = from q in db.Quizes
where q.Id equals id
select new QuizDomainObject()
{
Id = q.Id,
// all other propeties,
// I'm still unclear about the structure of your
// database and how it interlates, you'll need
// to figure out the query correctly here
IsClosed = from q in ....
};
return quiz;
}
}
}
Re: your comment
The join to QuestionLevels is making it think there are two contexts... but really there shouldn't be because the QuestionLevels should contain in-memory objects
I believe that if you join on simple types rather than objects you'll avoid this problem. The following might work for you:
return from ql in QuestionLevels
join q in query
on ql.LevelId equals q.Questions.Select(x => x.Level).Single().LevelId
into qs
(and if this doesn't work then construct some anonymous types and join on the Id)
The problem is that joining on the Level objects causes EF to do some under-the-covers magic - find the objects in the database and perform a join there. If you tell it to join on a simple type then it should send the values to the database for a SELECT
, retrieve the objects and stitch them together back in your application layer.