2

我正在尝试建立多对一关系。表示“许多”的实体具有指向父实体的导航属性。它看起来像这样:当仅填充相关对象的ID时导航属性未加载

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 
} 

所以,当我插入上面的实体,我从应用程序到实体的RFI(不是整个项目实体)经过专案编号。一切都很好。我遇到的问题是,当我将Rfi对象从数据库中拉出时,ProjectId正在填充,但项目实体为空。默认情况下,我使用“延迟加载”。我是否也需要在Project实体上指定导航属性?我真的不想。除非,我可以在我的Rfi上执行映射来完成此操作。

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

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

我最终什么事做,我在服务层我这样称呼它:

public Rfi FindByNumber(string number) 
{ 
    var rfi = rfiRepository.GetQuery(r => r.Number == number).Include(r => r.Project).Single; 
    return rfi 
} 
+0

'Project'和'Document'类是怎么看的?你不一定需要另一边的导航属性。你所描述的通常应该起作用。该问题可能隐藏在其他类或任何其他映射中。 – Slauma 2011-05-26 20:46:59

+0

我更新了代码示例。文档来自BaseEntity类型。 – DDiVita 2011-05-26 21:17:55

+0

您使用的是SQL Server吗?我认为'DatabaseGeneratedOption.Identity'不适用于SQL Server中的'Guid'(虽然模型允许这种设置,但它不是数据库中的标识)。但这可能不是你问题的原因。是否渴望加载'Project'属性的'Include'工作? – Slauma 2011-05-26 21:41:15

回答

3

原来我的广告载体创建的映射已在数据库中创建一个重复的ID。例如,我在数据库中有ProjectIdProject_ID。当新项目保存到上下文中时,我正在填充ProjectId,但_ID未被填充。这是EF 4.1正在使用的关联数据。在我的映射中,我正在设置项目,所以它不会CascadeOnDelete。这是我的映射看起来像:

HasOptional(rfi => rfi.Project) 
    .WithOptionalDependent() 
    .WillCascadeOnDelete(false); 

此映射在数据库中创建2个ID。一旦我删除了映射,一切正常。我只需要找出正确的映射,以便我可以删除CascadeOnDelete,使属性可选,并且只有一个ID。

我想通过EF Power Tools的帮助。您可以将您的数据库逆向工程化为POCO。我将上面的行改为:

HasOptional(r => r.Project) 
    .WithMany() 
    .HasForeignKey(r => r.ProjectId) 
    .WillCascadeOnDelete(false); 

即使流利的接口映射也有点难以掌握。为了理解EF中映射关系的方式,我使用表和外键分配创建了一个简单的数据库。然后我首先使用Power Tools的选项来进行反向工程代码。辉煌!

10

你必须让你的导航性能virtual为延迟加载工作。

虽然这在实施方面很有意义,但EF忽略问题和仅返回null的策略是一个糟糕的设计决策。

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

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


您也可以尝试明确指定FK /导航性能:

public Guid ProjectId { get; set; } 
[ForeignKey("ProjectId")] 
public virtual Project Project { get; set; } 
+0

他们是?如果你看看我的Rfi对象,这些属性被设置为虚拟的。 – DDiVita 2011-05-27 12:36:21

+0

@DDiVita:哦,我看到一些不属于(所有者,评论)的属性,并没有真正检查'Project'。尝试使这些虚拟,并检查我最后的编辑了。 – 2011-05-27 12:44:07

+0

进行了更改,但仍然无法正常工作。 – DDiVita 2011-05-27 12:53:45