私が取り組んでいるサイトでは、標準的なソーシャル ネットワーキング パラダイムである Friends と FriendRequests を採用しています。
私のユーザーと友達リクエストのクラスは次のとおりです。
public class User
{
public int Id { get; set; }
public ICollection<FriendRequest> FriendRequests { get; set; }
}
public class FriendRequest
{
public int UserId { get; set; }
public int FriendId { get; set; }
public DateTime RequestDate { get; set; }
public User User { get; set; }
public User Friend { get; set; }
}
私の流暢なマッピングは次のとおりです。
modelBuilder.Entity<User>()
.HasMany(u => u.FriendRequests)
.WithRequired(f => f.User)
.HasForeignKey(f => f.UserId);
modelBuilder.Entity<FriendRequest>()
.HasKey(f => new { f.UserId, f.FriendId });
modelBuilder.Entity<FriendRequest>()
.HasRequired(f => f.Friend)
.WithMany()
.HasForeignKey(f => f.FriendId);
私は 2 人のテスト ユーザー (ユーザー 22 とユーザー 18) で作業しています。
ユーザー 22 は、データベースにユーザー 18 からの友達リクエストを持っています。
UserId FriendId DateRequested RequestStatus DateResponded
22 18 2012-05-28 16:48:00 -1 NULL
今奇妙なビット:
このテストを受けてください:
public void FriendRequestTests()
{
var user22 = userRepository.FindById(22);
Console.WriteLine(user22.FriendRequests.Count); // Count: 1
var request = user22.FriendRequests[0];
var friend = request.Friend; // Null
}
問題は、request.Friend が null であることです (ただし、他のすべての値は入力されています)。
同じテストをもう一度実行しますが、最初に user18 をフェッチします (ただし、何もしません)。
public void FriendRequestTests()
{
var user18 = userRepository.FindById(18); // do nothing with this
var user22 = userRepository.FindById(22);
Console.WriteLine(user22.FriendRequests.Count); // Count: 1
var request = user22.FriendRequests[0];
var friend = request.Friend; // correct user (user18)
}
この動作は、フレンド リクエストと一貫して見られます。フレンドであるユーザーがセッションで以前にアクセスされたことがある場合、request.Friend は null ではありません。フレンドがセッションで一度もアクセスされていない場合、request.Friend は常に null です。
この奇妙さの原因は何ですか?どうすれば修正できますか?
さらに、外部キー関係が常に左外部結合によってフェッチされるべきであることをマッピングで定義する方法はありますか? NHibernate でこれができることは知っていますが、EF は私にとって初めてです。