我刚刚开始使用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;
}
查询确实返回正确的投票实体,但投票对象的两个用户属性为空。框架是否应该使用投票表中引用的用户的外键填充这些属性?
答案 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属性,你应该很高兴。