EF5 如何获取域对象的导航属性列表 [英] EF5 How to get list of navigation properties for a domain object

查看:31
本文介绍了EF5 如何获取域对象的导航属性列表的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在研究 EF 5 Code-First 解决方案,我正在尝试使用存储库模式使用修改后的实体更新现有实体:

I'm working on an EF 5 Code-First solution and I am trying to update an existing entity with a modified one using the Repository pattern:

    public void UpdateValues(T originalEntity, T modifiedEntity)
    {
        _uow.Context.Entry(originalEntity).CurrentValues.SetValues(modifiedEntity);

我的简化域对象如下所示:

My simplified domain object looks like this:

public class PolicyInformation : DomainObject
{
     //Non-navigation properties
     public string Description {get;set;}
     public bool Reinsurance {get;set;}
     ...
     //Navigation properties
     LookupListItemFormType FormType {get;set;}
     ...
}

我遇到的问题是 CurrentValues.SetValues(modifiedEntity); 方法似乎只更新标量和复杂类型属性,而不是导航属性.我已经看到很多人发生这种情况,但仍然不知道为什么会这样.但是,我发现如果我在执行 UpdateValues 后手动设置这些导航属性,一切正常:

The problem I have is that the CurrentValues.SetValues(modifiedEntity); method seems to be updating only scalar and complex type properties but not Navigation properties. I've seen this happening to a lot of people and still don't know why that is. However, I figured out that if I set those navigation properties manually after executing my UpdateValues everything works fine:

            _policyInfoRepo.UpdateValues(existingPolicyInfo, info);
            existingPolicyInfo.FormType = info.FormType;

问题是,因为我使用通用存储库:如何在我的域对象中获取导航属性列表?也许通过 linq、反射或任何其他方式,以便我的存储库中的更新方法可以遍历它们并自动设置它们?

The question is, since I use a generic repository: How can I get a list of Navigation properties in my domain object? Perhaps through linq, reflection, or any other way so my update method in my repository can loop through them and set them automatically?

像这样:

    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
        }

谢谢!

推荐答案

我使用 EF6 编写了以下内容,但我相信它都与 EF5 兼容.代码背后的总体思路是使用 a System.Data.Metadata.Edm 获取导航属性,并使用对这些属性名称的反射来获取要更新的对象的真实属性.

I wrote the following using EF6, but I believe it is all compatible with EF5. The general idea behind the code is to use the excellent classes in a System.Data.Metadata.Edm to get the navigation properties and use reflection on those property names to get the true properties of the object for updating.

我想让我的示例尽可能通用且完整.在提问者的情况下,他显然只是将上下文"替换为_uow.Context".

I wanted to make my example as generic yet complete as possible. In the asker's case, he'd just obviously replace "context" with "_uow.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;
    }
}

这篇关于EF5 如何获取域对象的导航属性列表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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