まず第一に、私は最初にEFコードと一般的な.NETに不慣れです。
私はMVC4、EF、JQuery、AutoMapper、その他のテクノロジーとライブラリで構築されているモバイルWebアプリに取り組んでいます。
これは紛らわしいかもしれませんが、私はそれを正しく説明するために最善を尽くします。
私は次のポコスを持っています:
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
.
.
}
そして私のコンテキストクラスでは:
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);
}
上記のTestオブジェクトは、TestIdを介してQuestionおよびUserStatusオブジェクトと1対多の関係にあります。各テストには独自の質問セットがあり、テストごとに4つの質問、質問ごとに20のuserStatuses 5があります)。名前が示すように、UserStatusテーブルにはユーザーステータスがあります。どのテストからどの質問にユーザーが回答したかを教えてくれます。
コントローラのコード:
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) });
ご覧のとおり、匿名クラスがあるため、currentUserIdでフィルタリングされたUserStatusesコレクションを取得して、現在のユーザーのステータスのみを取得できます。この時点ですべてが正常に機能します。
これが私がする必要があることです:
各質問は独自のステータスを知る必要があるため、QuestionテーブルとUserStatusテーブルの間の1対1の関係になります。
私のコンテキストクラスでは、以下を追加しました。
modelBuilder.Entity<Question>()
.HasRequired(x => x.UStatus)
.WithOptional();
そして私が持っていた質問オブジェクトで:
public virtual UserStatus UStatus { get; set; }
また、linqステートメントを次のように変更しました。
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) });
結果:
UStatusプロパティには各質問のデータがありましたが、現在のユーザー用でも適切なテスト用でもありませんでした。質問テーブルから同じQuestionIdを持つ、最初に遭遇したレコードを取得したように見えました。ダメ。
そこで、関係を1対多に変更しました。
私のコンテキストクラスでは、次のものを置き換えました。
modelBuilder.Entity<Question>()
.HasRequired(x => x.UStatus)
.WithOptional();
と:
modelBuilder.Entity<Question>()
.HasKey(a => new { a.QuestionId })
.HasMany(s => s.UStatus);
質問オブジェクトのUStatusプロパティを次のように変更しました。
public virtual ICollection<UserStatus> UStatus { get; set; }
linqステートメントから以下を削除しました
QuestionStatus = test.Questions.Select(u=>u.UStatus),
今回は正しいデータを取得できましたが、最初の4つの質問のみで、残りはnullでした。
もうどうしたらいいのかわからない。お願い助けて。