导航属性在CTP4 Code First EF4 Feature中查询后为空

时间:2010-08-11 13:02:32

标签: c# entity-framework-4 code-first

我刚刚开始使用CTP4和Code-First。我有一个可能的交友网站的以下设置:

public class User
{
    [Key]
    public int Id { get; set; }
    [Required]
    public string LoginName { get; set; }
    [Required]
    public string Firstname { get; set; }
    [Required]
    public string Lastname { get; set; }

    public string Street { get; set; }
    [Required]
    public string Zip { get; set; }
    [Required]
    public string City { get; set; }
    [Required]
    public bool Gender { get; set; }
    [Required]
    public int SoughtGender { get; set; }
    [Required]
    public string Password { get; set; }
    [Required]
    public double Latitude { get; set; }
    [Required]
    public double Longitude { get; set; }
}

 public class Vote
{
    [Key]
    public int ID { get; set; }
    [Required]
    public User Voter { get; set; }
    [Required]
    public User TargetUser { get; set; }
    [Required]
    public int Decision { get; set; }
    [Required]
    public DateTime Timestamp { get; set; }
}

 public class MySQLContext : DbContext
{
    public MySQLContext (string constring)
        : base(constring)
    { }

    public DbSet<User> Users { get; set; }
    public DbSet<Vote> Votes { get; set; }

    protected override void OnModelCreating(System.Data.Entity.ModelConfiguration.ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Vote>().HasRequired(b => b.Voter).WithMany();
        modelBuilder.Entity<Vote>().HasRequired(b => b.TargetUser).WithMany();
        base.OnModelCreating(modelBuilder);

    }
}

现在,框架可以很好地使用所有正确的密钥创建数据库。现在我插入了一些虚拟数据并启动了以下查询:

public override IEnumerable<Domain.Vote> FindVotes(Domain.User user)
    {
        var query = from v in context.Votes where v.Voter.Id == user.Id select v;
        return from v in query.AsEnumerable() select v;
    }

查询确实返回正确的投票实体,但投票对象的两个用户属性为空。框架是否应该使用投票表中引用的用户的外键填充这些属性?

2 个答案:

答案 0 :(得分:10)

让我给你一些关于EF的背景知识,这样你就可以理解它是如何工作的。从第1天起的EF仅支持显式加载,如下面的

Customer.Orders.Load();

嗯,反馈不受社区欢迎,开发人员想要延迟加载。为了支持延迟加载,EF团队表示必须将导航属性标记为虚拟。因此,在运行时,Ef会创建一个从您的实体派生的代理对象,并覆盖该虚拟属性。以下是此类代码的示例。

public class Customer
{
   public string Name{get;set;}
   public virtual ICollection<Order> Orders{get;set;}
}

在运行时,有一个实现IEntityWithChangeTracker的代理,集合的具体类型是自版本1以来一直存在的entitycollection。

public class CustomerProxy:Customer,IEntityWithChangeTracker
{
private ICollection<Order> orders;
   public override ICollection<Order> Orders
   {
        if(orders == null)
       {
           orders = new EntityCollection<Order>();
           orders.Load();
       }
       return orders;
   }
}

答案 1 :(得分:2)

将您的课程更改为以下

public class Vote {
    [Key]
    public int ID { get; set; }
    [Required]
    public virtual User Voter { get; set; }
    [Required]
    public virtual User TargetUser { get; set; }
    [Required]
    public int Decision { get; set; }
    [Required]
    public DateTime Timestamp { get; set; }
}

注意我已将虚拟添加到选民和&amp;&amp; TargetUser属性,你应该很高兴。