导航属性不加载时,相关对象的唯一标识填充 [英] Navigation Property not loading when only the ID of the related object is populated
问题描述
我想建立一个多到一的关系。表示多的实体有一个导航属性指回父实体。它看起来是这样的:
公共抽象类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屋!