我使用实体框架5码首先这个实体类:
public class Survey
{
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int ID { get; set; }
public string SurveyName { get; set; }
[Required]
public int ClientID { get; set; }
[ForeignKey("ClientID")]
public virtual Client Client { get; set; }
}
而在我的控制器的创建方法我这样做:
Survey entity = new Survey()
{
SurveyName = "Test Name",
ClientID = 4
};
db.Surveys.Add(entity);
db.SaveChanges();
Client c1 = entity.Client; //Why is this null?
Client c2 = db.Clients.Find(entity.ClientID); //But this isn't?
string s2 = c2.ClientName;
string s1 = c1.ClientName; //null reference thrown here
客户端的导航属性保持的SaveChanges后空。 我期待的调用,因为外键的存在是为了从数据库中加载客户端。 它为什么这样做呢?
编辑代码在这里来自当我的控制器都依赖DbContext
。 我得到这个工作,我不久后重新分解使用存储库和工作单位的代码。 这一举动的一部分的事实,它只是感觉不对使用驱动Create
时,我想用new
。 发生了什么事,然后是我打一个问题是如何确保代理使用存储库模式时创建 。
为了确保导航属性的懒加载一定会给你所创建的父母,你不能创建后Survey
与new
运营商,但通过上下文实例的方式创建它,因为它会实例化一个动态代理,它能够懒洋洋地加载相关的Client
。 这就是什么DbSet<T>.Create()
方法用于:
Survey entity = db.Surveys.Create();
entity.SurveyName = "Test Name";
entity.ClientID = 4;
db.Surveys.Add(entity);
db.SaveChanges();
Client c1 = entity.Client;
string s1 = c1.ClientName;
// will work now if a Client with ID 4 exists in the DB
只是强调:这不是行entity.ClientID = 4;
或db.Surveys.Add(entity);
或db.SaveChanges
加载从DB客户端,但该线Client c1 = entity.Client;
(延迟加载)。
就像@NicholasButler说,打电话SaveChanges
做什么它在锡说-你可以看到这一点,如果您调试代码:对智能跟踪输出将显示它已用于插入生成的SQL /更新你坚持,但不会有后续选择。
请记住,除非你是预先加载(使用Include
法),相关实体不加载进行检索时,所以按理说,创建/更新他们将不会。
实体框架(从我认为4.1及以上版本),支持延迟加载。 这意味着,如果它的启用,这样的代码Client c1 = entity.Client;
应该加载该Client
对象。 需要明确的是,这种操作不直接相关SaveChanges
调用。
它将支付检查是否db.Configuration.LazyLoadingEnabled
设置为true
。 如果没有,尝试将其设定为true
,看看Client c1 = entity.Client;
仍然是零。
总之,调用SaveChanges
不会触发负荷,但如果启用了延迟加载,访问entity.Client
如果它尚未加载应触发实体的负荷。
编辑:
我应该尽管这个较早,但你不会你上越来越懒加载Survey entity
对象。 其原因是,EF通过创建从一个派生的类,但覆盖标记为属性的工作延迟加载魔virtual
支持延迟加载。 为此,它会在您执行检索,所以你的entity
对象将不会延迟加载任何东西,因为它主张。
试试这只是您的来电后SaveChanges
:
Survey entity2 = db.Surveys.Find(entity.ID);
Client c1 = entity2.Client;
这应该表现出你是以后的行为。
您需要定义上的所有属性Survey
类虚拟,使延迟加载。
见http://msdn.microsoft.com/en-us/library/vstudio/dd468057(v=vs.100).aspx以获取更多信息。
我期待的调用,因为外键的存在是为了从数据库中加载客户端。 它为什么这样做呢?
它没有这样做,因为你还没有要求它。 调用后SaveChanges()
,EF没有引用的行中的数据,它不会让一个潜在的冗余数据库调用得到它。
调用db.Clients.Find(...
告诉EF去从数据库中,这就是为什么它返回对象读取该行。
文章来源: Entity Framework: I set the foreign key, SaveChanges then access the navigation property, but it doesn't load the related entity. Why not?