【问题标题】:New Poco Entity with null navigation property EF Code first具有空导航属性 EF Code 的新 Poco 实体
【发布时间】:2014-10-15 11:23:08
【问题描述】:

我首先使用实体​​框架代码。这是我的 poco 课程:

public class BusinessPartner
{
    [Key]
    public int BusinessPartnerID { get; set; }
    [Required]
    [StringLength(255)]
    public string Title { get; set; }
    [StringLength(255)]
    public string Address { get; set; }

    public virtual ICollection<BusinessPartnerLanguage> BusinessPartnerLanguage { get; set; }
}

public class Language
{
    [Key]
    public int LanguageID { get; set; }
    [Required]
    [StringLength(255)]
    public string Title { get; set; }
    [Required]
    public bool Active { get; set; }

    public virtual ICollection<BusinessPartnerLanguage> BusinessPartnerLanguage { get; set; }
}

public class BusinessPartnerLanguage
{
    [Key, Column(Order = 0)]
    public int BusinessPartnerID { get; set; }
    [Key, Column(Order = 1)]
    public int LanguageID { get; set; }
    [Required]
    public bool Default { get; set; }
    public virtual BusinessPartner BusinessPartner { get; set; }
    public virtual Language Language { get; set; }
}

当我在控制器中创建新实体时,例如:

BusinessPartner bp = new BusinessPartner();

它的导航属性 - bp.BusinessPartnerLanguage 为空,
所以如果我做类似的事情:

bp.BusinessPartnerLanguage.Add(someEntity);

我得到空异常。我设法通过将虚拟 ICollection 属性更改为:

   private ICollection<BusinessPartnerLanguage> _BusinessPartnerLanguage;
   public virtual ICollection<BusinessPartnerLanguage> BusinessPartnerLanguage
   {
       get { return this._BusinessPartnerLanguage ?? (this._BusinessPartnerLanguage = new HashSet<BusinessPartnerLanguage>()); }
       set { _BusinessPartnerLanguage = value; }
    }

但我想知道为什么这不能正常工作,是否有更好的方法来解决这个问题。提前致谢。

【问题讨论】:

    标签: c# entity-framework ef-code-first navigation-properties


    【解决方案1】:

    这是因为它只是一个POCO实体,如果该属性从未设置过,它将为空。

    从 db 上下文中检索对象时,如果启用代理,EF 将创建一个代理实体。如果您将该属性标记为虚拟,则对虚拟属性的任何访问都将加载关系并初始化集合(如果它为空)。急切加载也是如此。

    但如果实体在数据库中不存在(新实体),则无法加载关系,它必须是现有实体。

    如果您有现有的 id,您可以通过编程方式创建代理,延迟加载将加载关系并初始化集合。但是你必须使用Create 方法而不是new 操作符。

    如果您创建一个代理实例,则不会创建代理实例 使用 new 运算符的实体。 - MSDN

    var context = ...
    int existingBPID = ...
    
    var bp = context.Set<BusinessPartner>().Create(); // BusinessPartnerLanguage = null
    bp.BusinessPartnerID = existingBPID;  // BusinessPartnerLanguage = null
    context.Entry(bp).State = EntityState.Unchanged; // BusinessPartnerLanguage = null
    var collection = bp.BusinessPartnerLanguage; // trigger lazy loading, BusinessPartnerLanguage != null
    

    您还可以将属性简化如下。

    private readonly ICollection<BusinessPartnerLanguage> _BusinessPartnerLanguage
        = new HashSet<BusinessPartnerLanguage>();
    public virtual ICollection<BusinessPartnerLanguage> BusinessPartnerLanguage
    {
        get { return _BusinessPartnerLanguage; }
    }
    

    【讨论】:

      猜你喜欢
      • 2013-10-28
      • 2011-04-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-10-10
      • 1970-01-01
      • 2017-12-22
      相关资源
      最近更新 更多