实体框架代码优先 - 奇怪的实体加载行为

时间:2012-05-29 10:08:41

标签: entity-framework ef-code-first

我正在开发的网站采用标准的社交网络范例:朋友和朋友请求。

我的用户和朋友请求课程如下:

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);

我正在与我的两个测试用户 - 用户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不为空。如果在会话中从未访问过该朋友,则request.Friend始终为null。

造成这种奇怪的原因是什么?如何解决? 此外,有没有办法在映射中定义外键连接总是应该由左外连接获取?我知道NHibernate允许你这样做,但EF对我来说是新的。

1 个答案:

答案 0 :(得分:2)

尝试将导航属性设置为virtual

这样的东西
public class User
{
    public int Id { get; set; }

    public virtual ICollection<FriendRequest> FriendRequests { get; set; }
}

public class FriendRequest
{
    public int UserId { get; set; }
    public int FriendId { get; set; }

    public DateTime RequestDate { get; set; }

    public virtual User User { get; set; }
    public virtual User Friend { get; set; }
}

如果你懒得加载你的ObjectContext,这可能会导致你的问题。