导航属性不加载时,相关对象的唯一标识填充 [英] Navigation Property not loading when only the ID of the related object is populated

查看:253
本文介绍了导航属性不加载时,相关对象的唯一标识填充的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想建立一个多到一的关系。表示多的实体有一个导航属性​​指回父实体。它看起来是这样的:

 公共抽象类BaseEntity 
{

///< ;总结>
///键字段的所有实体
///< /总结>
///
[键,DatabaseGenerated(DatabaseGeneratedOption.Identity)
公众的Guid标识{搞定;组; }


///<总结>
///日期实体创建
///< /总结>
公众的DateTime dateCreated会获得{;组; }

///<总结>
///最后修改日期
///< /总结>
公众的DateTime DateModified {搞定;组; }

///<总结>
///跟踪行版本的用于并发
///< /总结>
[时间戳]
公共字节[] {RowVersion获得;组; }

}

公共抽象类文件:BaseEntity
{
#地区的原始属性


/ //<总结>
///布尔值,以确定是否文件是处于激活状态
///&下; /总结>
公共布尔IsActive {搞定;组; }

///<总结>
///文件的意见和信息
///< /总结>
[必填]
公共字符串描述{搞定;组; }

#endregion

#地区的导航属性

公众的ICollection<&评论GT;评论{搞定;组; }

///<总结>
/// FK回用户谁拥有文件
///< /总结>
//公众的Guid OWNERID {搞定;组; }

公众的Guid OWNERID {搞定;组; }
///<总结>
///导航返回用户谁拥有文件
///< /总结>
公众用户所有者获得{;组; }

#endregion
}

公共类项目:BaseEntity
{
公共字符串名称{;组; }
公共字符串ProjectNumber {搞定;组; }
公共字符串描述{搞定;组; }

公共字符串CreatedBy {搞定;组; }
公共字符串ModifiedBy {搞定;组; }
公共字符串货币{搞定;组; }

#地区的导航属性

公共虚拟地址地址{搞定;组; }
公共虚拟企业编码企业编码{搞定;组; }
公共虚拟的ICollection<联系与GT; TeamMembers {搞定;组; }

#endregion
}

公共类RFI:文件
{
公共串号{搞定;组; }

#地区的导航属性

//这回指项目实体
公共虚拟的Guid专案编号{搞定;组; }
公共虚拟项目项目{搞定;组; }

#endregion
}



所以,当我插入上述实体,我路过专案编号从应用程序到实体的RFI(不是整个项目实体)。一切都节省了罚款。我遇到的问题是,当我拉RFI对象背出库,正在填充专案编号,但该项目的实体为空。我使用延迟加载,默认情况下。我需要指定的项目实体的导航属性,也?我真的不想要。除非,我可以对我的RFI映射做到这一点。



更​​新:
我以为EF 4.1将加载我的对象我,但现在看来,有时我需要明确包括我想要加载哪些对象。我不完全知道为什么。我使用一个存储库来查询我的实体。下面是我用来查询RFI对象方法:

 公开的IQueryable< TEntity> GetQuery(表达式来; Func键< TEntity,布尔>>谓语)
{
返回_context.Set< TEntity>()AsQueryable已()。
}



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

 公共RFI FindByNumber(串号)
{
VAR RFI = rfiRepository.GetQuery(R = GT ; r.Number ==号).INCLUDE(R = GT; r.Project)。单;
返回RFI
}


解决方案

原来我的媒体资源相关联是在数据库中创建一个重复的ID创建的映射。我有,例如,专案编号 PROJECT_ID 在数据库中。我被填充专案编号当一个新项目被保存到上下文,但 _ID 没有被填充。这是EF 4.1使用到的相关数据。在我的映射我特林设置的项目,所以它不会 CascadeOnDelete 。这是我的映射是这样的:

  HasOptional(RFI => rfi.Project)
.WithOptionalDependent()
.WillCascadeOnDelete(假);

这映射已在数据库中创建的ID 2。一旦我删除的映射一切工作。我只需要找出正确的映射,所以我可以删除 CascadeOnDelete ,使物业可​​选,并且只有一个ID。



我想如果用出去的 EF电动工具的。您可以反向工程数据库到波苏斯。我改变了上述行:

  HasOptional(R = GT; r.Project)
.WithMany()
.HasForeignKey(R = GT; r.ProjectId)
.WillCascadeOnDelete(假);



即使有一个流畅的接口映射是有点难以掌握。要了解关系是如何在EF映射我创建了一个简单的数据库,我的表和外键分配。然后,我第一次使用电动工具'逆向工程代码选择。辉煌!


I am trying to establish a many-to-one relationship. The entity that represents the "many" has a navigation property pointing back to the parent entity. It looks like this:

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
}

So, when I insert the above entity, I am passing the ProjectId from the application into the Rfi entity (not the entire Project entity). Everything saves fine. The issue I am having is, when I pull the Rfi object back out of the database, the ProjectId is being populated, but the Project entity is null. I am using Lazy Loading, by default. Do I need to specify a navigation property on the Project entity, too? I don’t really want to. Unless, I can perform a mapping on my Rfi to accomplish this.

Update: I assumed EF 4.1 would load my objects for me, but it seems, sometimes I need to explicitly include what objects I want to load. I am not entirely sure why. I am using a repository to query my entities. Here is the method I used to query the Rfi object:

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

What I ended up doing, in my Service layer I call it like this:

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

解决方案

Turns out the mapping I created for the proeprty was creating a duplicate ID in the database. I had, for example, ProjectId and Project_ID in the database. I was populating ProjectId when a new item was saved to the context, but the _ID was not being populated. This is what EF 4.1 is using to relate the data. In my mapping I was tring to set the Project so it would not CascadeOnDelete. This is what my mapping looks like:

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

This mapping was creating 2 IDs in the database. Once I removed the mapping everything was working. I just need to figure out the correct mapping so I can remove the CascadeOnDelete, make the property optional, and only have one ID.

I figured if out with the Help of EF Power Tools. You can reverse engineer your DB into POCOs. I changed the above line to:

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

Even with a fluent interface mappings are a bit difficult to master. To understand how relationships are mapped in EF I created a simple database with my tables and foreign key assignments. I then used the Power Tools’ option for reverse engineering code first. Brilliant!

这篇关于导航属性不加载时,相关对象的唯一标识填充的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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