实体框架:我设置外键,SaveChanges然后访问导航属性,但它不加载相关实体。为什么不? [英] Entity Framework: I set the foreign key, SaveChanges then access the navigation property, but it doesn't load the related entity. Why not?

查看:245
本文介绍了实体框架:我设置外键,SaveChanges然后访问导航属性,但它不加载相关实体。为什么不?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

  public class Survey 
{
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int ID {get;组; }

public string SurveyName {get;组;

[必需]
public int ClientID {get;组; }

[ForeignKey(ClientID)]
public virtual Client Client {get;组; }
}

在我的Controller的Create方法中我执行此操作:

 调查实体=新调查()
{
SurveyName =测试名称,
ClientID = 4
};
db.Surveys.Add(entity);
db.SaveChanges();
客户端c1 = entity.Client; //为什么这是null?
客户端c2 = db.Clients.Find(entity.ClientID); //但这不是吗?

string s2 = c2.ClientName;
string s1 = c1.ClientName; // null引用抛出

客户端导航属性在SaveChanges后保持为空。我希望调用从数据库加载客户端,因为外键存在。为什么不这样做?



编辑
这里的代码来自于我的控制器依赖于的DbContext 。不久之后,我得到这个工作,我重新考虑了代码使用仓库和工作单位。这个举动的一部分是由于我想使用新的而使用创建感到错误的事实。那么发生了什么事情就是我遇到了一个问题:如何确保在使用存储库模式时创建代理

解决方案

为确保导航属性的延迟加载在您创建父级后可以工作,您不得创建调查新的运算符,但通过上下文实例创建它,因为它会实例化一个能够懒惰的动态代理加载相关的客户端。这就是 DbSet< T> .Create()方法是:

  Survey entity = db.Surveys.Create(); 

entity.SurveyName =Test Name;
entity.ClientID = 4;

db.Surveys.Add(entity);
db.SaveChanges();

客户端c1 = entity.Client;
string s1 = c1.ClientName;
//现在将工作,如果ID为4的客户端存在于DB

只是为了强调:不是行 entity.ClientID = 4; db.Surveys.Add(entity); db.SaveChanges 从数据库加载客户端,但行客户端c1 = entity.Client; (延迟加载) 。


I am using this Entity class with Entity Framework 5 Code First:

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

And in my Controller's Create method I do this:

    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

The Client navigation property remains null after SaveChanges. I expected the call to load the Client from the database because the foreign key exists. Why didn't it do that?

EDIT The code here comes from when my controllers were dependent on DbContext. Not long after I got this working I re-factored the code to use repositories and a unit of work. Part of that move was driven by the fact that it just felt wrong to use Create when I wanted to use new. What happened then was that I hit a problem with how to ensure proxies are created when using the repository pattern.

解决方案

To ensure that lazy loading of a navigation property will work after you've created the parent you must not create the Survey with the new operator but create it by means of the context instance because it will instantiate a dynamic proxy that is capable to lazily load the related Client. That's what the DbSet<T>.Create() method is for:

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

Just to emphasize: It's not the line entity.ClientID = 4; or db.Surveys.Add(entity); or db.SaveChanges that loads the client from the DB, but the line Client c1 = entity.Client; (lazy loading).

这篇关于实体框架:我设置外键,SaveChanges然后访问导航属性,但它不加载相关实体。为什么不?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆