【问题标题】:Entity Framework Navigation Properties on Derived Types派生类型上的实体框架导航属性
【发布时间】:2015-05-12 14:27:46
【问题描述】:

我是 EF 新手,遇到了障碍。我正在尝试获取从基本类型派生的实体类型的导航属性列表。我打算用....

ObjectContext objectContext = ((System.Data.Entity.Infrastructure.IObjectContextAdapter)context).ObjectContext;
var entitySetElementType = objectContext.CreateObjectSet<DerivedType>().EntitySet.ElementType;
foreach(var navigationProperty in entitySetElementType.NavigationProperties)
{ //need PropertyInfo here}

这是我了解到我无法获得派生类型的 ObjectSet 的地方。抛出的异常是

"没有为指定的实体类型定义实体集 'SurveyDALv2.Model.Correspondence'。如果 'SurveyDALv2.Model.Correspondence' 是派生类型,使用基类 而是输入。”

我知道我可以使用

获取派生实体的 ObjectQuery
objectContext.CreateObjectSet<BaseType>().OfType<DerivedType>()

但是,这对获取导航属性列表没有帮助(除非我遗漏了一些东西)。我看不到如何访问派生实体类型的 EntitySet.NavigationProperties。

非常感谢任何帮助。

【问题讨论】:

  • 从未尝试过使用核心上下文,但您可以试试这个:CreateObjectSet&lt;BaseType&gt;().OfType&lt;DerivedType&gt;() 而不是 CreateObjectSet&lt;DerivedType&gt;() 吗?
  • 谢谢,但我正在寻找在派生类型实体上定义的导航属性列表。这(stackoverflow.com/questions/17886725/… 可以很好地获取导航属性列表,除非它是派生类型实体)(来自 marsman 的答案)

标签: c# entity-framework


【解决方案1】:
public EntityType ElementType(Type entityType)
{
    var type = ObjectContext.GetObjectType(entityType);
    var objectContext = ((IObjectContextAdapter)this).ObjectContext;
    EntityType elementType;
    if (objectContext.MetadataWorkspace.TryGetItem(type.FullName, DataSpace.OSpace, out elementType))
    {
        return elementType;
    }
    return null;
}

【讨论】:

    【解决方案2】:

    我设法使下面的代码工作,我希望它对你有帮助。

        ObjectContext objectContext = ((System.Data.Entity.Infrastructure.IObjectContextAdapter)context).ObjectContext;
        EntityContainer container = objectContext.MetadataWorkspace.GetEntityContainer(objectContext.DefaultContainerName, DataSpace.CSpace);
    
        //Only works if you keep the default entity associations names pattern
        //ie: ClassName.NavigationProperty
        var t = container.AssociationSets.Where(a => a.Name.Contains(typeof(DerivedType).Name));
    
        foreach (AssociationSet navigationProperty in t)
        {
            String p = navigationProperty.Name;
            var propInfo = typeof(DerivedType).GetProperty(p.Substring(typeof(DerivedType).Name.Length+1));
        }
    

    【讨论】:

    • 这似乎适用于我的大多数实体类,但我有一些实体名称扩展了其他实体名称。我有一个 Correspondence 类和 CorrespondenceChain 类,以及 CorrespondenceChainItem 类。所以我的类名阻止了 'Where(a=>a.Name.Contains' 只返回正确的关联集。T
    • 这确实有帮助。我真的只是想在添加和保存更改之前发现实体的导航属性并将其重新附加到上下文中。添加时我得到了重复的实体,因为我正在使用分离的上下文。我只是要写一些特定类型的东西来附加我知道存在的导航属性。谢谢
    • 考虑到你的类名,你可以使用Where(a =&gt; a.Name.Contains(typeof(DerivedType).Name+".")) 之类的东西注意:. 可能已被字符串中的_ 替换。无论如何,如果您在复制实体时遇到问题,也许您没有以正确的方式检索您的实体(包含用于延迟加载),我猜您没有将 FK 属性添加到您的模型中,从而允许您根据已知的 FK 加载导航属性.
    • 这里总结了我遇到的问题link,我正在从访问数据库迁移数据。我将使用 fk 属性来分配导航属性,这应该可以防止重复。感谢您的帮助。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-29
    • 2016-05-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多