当仅填充相关对象的ID时,不加载导航属性

DDi*_*ita 3 c# entity-relationship navigation-properties ef-code-first entity-framework-4.1

我正在努力建立多对一的关系.表示"many"的实体具有指向父实体的导航属性.它看起来像这样:

public abstract class BaseEntity
{

    /// <summary>
    /// Key Field for all entities
    /// </summary>
    /// 
    [Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public Guid Id { get; set; }


    /// <summary>
    /// Date entity was created
    /// </summary>
    public DateTime DateCreated { get; set; }

    /// <summary>
    /// Last date Modified
    /// </summary>
    public DateTime DateModified { get; set; }

    /// <summary>
    /// keep track of Row Version used for concurrency
    /// </summary>
    [Timestamp]
    public Byte[] RowVersion { get; set; }

}

public abstract class Document : BaseEntity
{
    #region Primitive Properties   


    /// <summary>
    /// Boolean value to determine if Document is in an active state
    /// </summary>
    public bool IsActive { get; set; }

    /// <summary>
    /// Document comments and information
    /// </summary>
    [Required]
    public string Description { get; set; }

    #endregion

    #region Navigation Properties

    public ICollection<Comment> Comments { get; set; }

    /// <summary>
    /// FK back to User who owns document
    /// </summary>
    //public Guid OwnerId { get; set; }

    public Guid OwnerId { get; set; }
    /// <summary>
    /// Navigation Back to User who owns document
    /// </summary>
    public User Owner { get; set; }

    #endregion
}

public class Project : BaseEntity
{
    public string Name { get; set; }
    public string ProjectNumber { get; set; }
    public string Description { get; set; }

    public string CreatedBy { get; set; }
    public string ModifiedBy { get; set; }
    public string Currency { get; set; }

    #region Navigation Properties

    public virtual Address Address { get; set; }
    public virtual CompanyCode CompanyCode { get; set; }
    public virtual ICollection<Contact> TeamMembers { get; set; }

    #endregion
}    

 public class Rfi : Document
 {
    public string Number { get; set; }

    #region Navigation Properties

    //This points back to a Project Entity
    public virtual Guid ProjectId { get; set; }
    public virtual Project Project { get; set; }

    #endregion
}
Run Code Online (Sandbox Code Playgroud)

因此,当我插入上述实体时,我将ProjectId从应用程序传递到Rfi实体(而不是整个Project实体).一切都很好.我遇到的问题是,当我将Rfi对象拉回数据库时,ProjectId正在填充,但Project实体为null.我默认使用Lazy Loading.我是否还需要在Project实体上指定导航属性?我真的不想.除非,我可以在我的Rfi上执行映射来完成此任务.

更新:我假设EF 4.1会为我加载我的对象,但似乎有时我需要明确包含我想要加载的对象.我不完全确定为什么.我正在使用存储库来查询我的实体.这是我用来查询Rfi对象的方法:

    public IQueryable<TEntity> GetQuery(Expression<Func<TEntity, bool>> predicate)
    {
       return _context.Set<TEntity>().AsQueryable();
    }
Run Code Online (Sandbox Code Playgroud)

我最终做了什么,在我的服务层我称之为:

public Rfi FindByNumber(string number)
{
     var rfi = rfiRepository.GetQuery(r => r.Number == number).Include(r => r.Project).Single;
     return rfi
}
Run Code Online (Sandbox Code Playgroud)

Die*_*hon 13

您必须使virtualLazy Loading的导航属性起作用.

虽然这在实施方面是有道理的,但EF忽略问题并且刚刚返回的策略null是一个糟糕的设计决策.

另一方面,NHibernate默认情况下不允许您使用虚拟所有属性的类.

为了避免这个问题,我写了一个测试,验证每个引用属性都标记为虚拟.这样我立即发现,而不是在路上处理奇怪的错误.


您还可以尝试显式指定FK/Navigation属性:

public Guid ProjectId { get; set; }
[ForeignKey("ProjectId")]
public virtual Project Project { get; set; }
Run Code Online (Sandbox Code Playgroud)