Ado*_*rez 4 entity-framework navigation-properties c#-4.0
我正在研究EF 5 Code-First解决方案,我正在尝试使用Repository模式更新现有实体并使用已修改的实体:
public void UpdateValues(T originalEntity, T modifiedEntity)
{
_uow.Context.Entry(originalEntity).CurrentValues.SetValues(modifiedEntity);
Run Code Online (Sandbox Code Playgroud)
我的简化域对象如下所示:
public class PolicyInformation : DomainObject
{
//Non-navigation properties
public string Description {get;set;}
public bool Reinsurance {get;set;}
...
//Navigation properties
LookupListItemFormType FormType {get;set;}
...
}
Run Code Online (Sandbox Code Playgroud)
我遇到的问题是该CurrentValues.SetValues(modifiedEntity);
方法似乎只更新标量和复杂类型属性,但不更新导航属性.我已经看到这种情况发生在很多人身上,但仍然不知道为什么会这样.但是,我发现如果我在执行后手动设置这些导航属性,UpdateValues
一切正常:
_policyInfoRepo.UpdateValues(existingPolicyInfo, info);
existingPolicyInfo.FormType = info.FormType;
Run Code Online (Sandbox Code Playgroud)
问题是,因为我使用通用存储库:如何在域对象中获取导航属性列表?也许通过linq,反射或任何其他方式,以便我的存储库中的更新方法可以循环遍历它们并自动设置它们?
像这样的东西:
public void UpdateValues(T originalEntity, T modifiedEntity)
{
//Set non-nav props
_uow.Context.Entry(originalEntity).CurrentValues.SetValues(modifiedEntity);
//Set nav props
var navProps = GetNavigationProperties(originalEntity);
foreach(var navProp in navProps)
{
//Set originalEntity prop value to modifiedEntity value
}
Run Code Online (Sandbox Code Playgroud)
谢谢!
我使用EF6编写了以下内容,但我相信它与EF5完全兼容.代码背后的一般思想是使用System.Data.Metadata.Edm中的优秀类来获取导航属性,并对这些属性名称使用反射来获取对象的真实属性以进行更新.
我想让我的例子尽可能通用但完整.在提问者的情况下,他显然会用"_uow.Context"替换"context".
public class MyClass<T> where T : class //T really needs to always be an entity,
//but I don't know a general parent type
//for that. You could leverage partial classes
//to define your own type.
{
public MyEntities context { get; set; }
public void UpdateValues(T originalEntity, T modifiedEntity)
{
//Set non-nav props
context.Entry(originalEntity).CurrentValues.SetValues(modifiedEntity);
//Set nav props
var navProps = GetNavigationProperties(originalEntity);
foreach (var navProp in navProps)
{
//Set originalEntity prop value to modifiedEntity value
navProp.SetValue(originalEntity, navProp.GetValue(modifiedEntity));
}
}
public List<System.Reflection.PropertyInfo> GetNavigationProperties(T entity)
{
List<System.Reflection.PropertyInfo> properties = new List<System.Reflection.PropertyInfo>();
//Get the entity type
Type entityType = entity.GetType();
//Get the System.Data.Entity.Core.Metadata.Edm.EntityType
//associated with the entity.
var entitySetElementType = ((System.Data.Entity.Infrastructure.IObjectContextAdapter)context).ObjectContext.CreateObjectSet<T>().EntitySet.ElementType;
//Iterate each
//System.Data.Entity.Core.Metadata.Edm.NavigationProperty
//in EntityType.NavigationProperties, get the actual property
//using the entityType name, and add it to the return set.
foreach (var navigationProperty in entitySetElementType.NavigationProperties)
{
properties.Add(entityType.GetProperty(navigationProperty.Name));
}
return properties;
}
}
Run Code Online (Sandbox Code Playgroud)
啊,LINQ(和using
)的荣耀:
public List<PropertyInfo> GetNavigationProperties(T entity)
{
var t = entity.GetType();
var elementType = ((IObjectContextAdapter)context).ObjectContext.CreateObjectSet<T>().EntitySet.ElementType;
return elementType.NavigationProperties.Select(np => entityType.GetProperty(np.Name)).ToList();
}
Run Code Online (Sandbox Code Playgroud)
这也可以通过一种static
方法实现,具有以下签名:
public static List<PropertyInfo> GetNavigationProperties<T>(DbContext context)
{
var t = typeof(T);
...
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
7693 次 |
最近记录: |