First of all, I'm new to the EF-code first and .NET in general.
Im working on a mobile web app thats being built with MVC4, EF, JQuery, AutoMapper & other technologies and libraries.
This might be confusing, but I will do my best to explain it right.
I have the following pocos:
public class Test
{
[Key]
public int TestId { get; set; }
.
.
Other properties
.
.
public virtual ICollection<Question> Questions { get; set; }
public virtual ICollection<UserStatus> UserStatuses { get; set; }
}
public class UserStatus
{
[Key]
public int UserStatusId { get; set; }
public int TestId { get; set; }
public string Customer { get; set; }
.
.
Other properties
.
.
}
public class Question
{
[Key]
public int QuestionId { get; set; }
public int TestId { get; set; }
.
.
Other properties
.
.
}
and in my context class i have:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
Database.SetInitializer<CmeContext>(null);
modelBuilder.Entity<Test>()
.HasKey(a => new { a.TestId })
.HasMany(s => s.Questions);
modelBuilder.Entity<Test>()
.HasKey(a => new { a.TestId })
.HasMany(s => s.UserStatuses);
}
The above Test object has a one-to-many relationship to Question and UserStatus objects through TestId. Each Test has it's own set of questions which are 4 questions per test, and 20 userStatuses 5 per question). As the name implies the UserStatus table has user statuses; it let me know which question(s) from what test was answered by a user.
The code in the controller:
var filtered = (from test in _ctxCmeContext.Test.Include("UserStatus").Include("Question")
where test.Program == "SomeProgram" && test.IssueDate.Value.Year == year && test.IssueDate.Value.Month == monthNumber
orderby test.IssueDate descending
select new { test,
Questions = test.Questions,
UserStatuses = test.UserStatuses.Where(x => x.Customer == currentUserId) });
As you see I have an anonymous class so I can get the UserStatuses collection filtered by currentUserId to get the statuses for the current user only. Everything works fine at this point.
Here's what I need to do:
Each question needs to know its own status, so it's a one-to-one relationship between the Question and UserStatus table
In my context class I added the following:
modelBuilder.Entity<Question>()
.HasRequired(x => x.UStatus)
.WithOptional();
and in the Question Object I had:
public virtual UserStatus UStatus { get; set; }
and I also modified my linq statement as follows:
var filtered = (from test in _ctxCmeContext.Test.Include("UserStatus").Include("Question").Include("UStatus")
where test.Program == "SomeProgram" && test.IssueDate.Value.Year == year && test.IssueDate.Value.Month == monthNumber
orderby test.IssueDate descending
select new { test,
QuestionStatus = test.Questions.Select(u=>u.UStatus),
Questions = test.Questions,
UserStatuses = test.UserStatuses.Where(x => x.Customer == currentUserId) });
The result:
the UStatus property had data for each question but it wasn't for the current user nor for the right test; it seemed to me that it just grabbed the first record it ecountered that had the same QuestionId from the Question table. No good.
so I changed the relationship to one-to-many:
In my context class I replaced:
modelBuilder.Entity<Question>()
.HasRequired(x => x.UStatus)
.WithOptional();
with:
modelBuilder.Entity<Question>()
.HasKey(a => new { a.QuestionId })
.HasMany(s => s.UStatus);
changed the UStatus property in the Question Object to:
public virtual ICollection<UserStatus> UStatus { get; set; }
and removed the following from the linq statement
QuestionStatus = test.Questions.Select(u=>u.UStatus),
This time I was able to get some correct data but only for the first 4 questions, and the rest were null
I don't know what to do anymore. Help me please.
With the Schema/POCO you provided and by analyzing your story, what I can summarize is this:
You want to identify, which question(s) from what test was answered by a user?
If this is what you mean, then by assuming that lazy loading
is enabled in your context
I can suggest a query similar to this:
var questions = context.Questions.Where( q => q.Test.Program == "someProgram"
&& q.Test.UserStatus.Any( us => us.UserId == currentUserId ));
It does the following:
someProgram
UserStatus
of the user currentUserId
Hence in the questions
collection you are having the answer for your problem.
My understanding of your problem might be wrong, but I believe it provides some hint to you.
在Question对象中,我创建了一个导航属性,返回到Test对象,从那里我可以知道每个问题的状态,因为UserStatus是Test对象中的一个子集合。
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.