实体框架代码优先:如何确定运行时用于导航属性的外键属性?

2024-03-26

我有一个实体框架 Code First DbContext,配置了以下实体。在此示例中,Bar 类是 Foo 类的子类。

public class Foo
{
    public Guid Id { get; set; }

    public virtual ICollection<Bar> Bars { get; set; }
}

public class Bar
{
    public Guid Id { get; set; }

    public Guid FooId { get; set; }

    public virtual Foo Foo { get; set; }
}

现在我知道,实体框架在内部理解 Foo 和 Bar 之间的关系是由外键 Bar.FooId 定义的。我想做的是在运行时使用表达式以某种方式提取这种关系。我想实现一个行为如下的方法:

var context = new FooBarDbContext();
var bar = context.Set<Bar>().First();

// I want this method to return bar.FooId when passed the expression b => b.Foo
object result = MyService.GetForeignKeyValue(bar, b => b.Foo); 

现在,在这个简单的示例中,我知道我只需获取 bar.FooId 即可完成。重点是,我正在编写一个类,我相信上面指定的 GetForeignKeyValue 方法对于用户来说是最干净的接口。

是否可以查询 DbContext 配置以确定哪个属性用作导航属性的外键? (假设有一个)


我实际上能够通过使用来确定外键属性获取依赖属性 http://msdn.microsoft.com/en-us/library/system.data.metadata.edm.navigationproperty.getdependentproperties.aspx的方法导航属性 http://msdn.microsoft.com/en-us/library/system.data.metadata.edm.navigationproperty%28v=vs.110%29.aspx class.

这是我(或多或少)用来获得我需要的代码:

object[] GetForeignKeyPropertyValues<TEntity, TRelatedEntity>(TEntity entity, Expression<Func<TEntity, TRelatedEntity>> navigationProperty)
{
    if (entity == null)
        return new object[] { };

    // Find the entity metadata in the object context.
    // (Assume you have access to the DbContext through the property CurrentDbContext.)
    var objectContext = (CurrentDbContext as IObjectContextAdapter).ObjectContext; 

    var metadataNamespace = ObjectContextAdapter.GetType().Namespace;

    var entityIdentity = metadataNamespace + "." + typeof(TEntity).Name; // HACK: This seems to work to retrieve the EntityType for an entity.
    var entityMetadata = objectContext.MetadataWorkspace.GetItem<EntityType>(entityIdentity, DataSpace.CSpace);

    // TODO: Verify that the entity metadata was found.

    // Get the navigation property metadata by parsing the name from the navigation property expression.
    var navigationPropertyName = GetPropertyName(navigationProperty);
    var navigationPropertyMetadata = entityMetadata.NavigationProperties.FirstOrDefault(np => np.Name == navigationPropertyName);

    // TODO: (JMB) Verify that the navigation property metadata was found.

    // Extract the foreign key columns from the navigation property.
    var foreignKeyPropertyMetadatas = navigationPropertyMetadata.GetDependentProperties();

    // Create property getters for each foreign key property.
    var foreignKeyPropertyGetters = foreignKeyPropertyMetadatas
        .Select(propertyMetadata => MakePropertyGetter<TEntity>(propertyMetadata.Name))
        .ToArray();

    // Execute the foreign key property getters to get the foreign key property values for the specified entity.
    var foreignKeyPropertyValues = foreignKeyPropertyGetters
        .Select(propertyGetter => propertyGetter(entity))
        .ToArray();

    return foreignKeyPropertyValues;
}

static string GetPropertyName<TEntity, TProperty>(Expression<Func<TEntity, TProperty>> navigationProperty)
{
    var lambda = navigationProperty as LambdaExpression;
    var member = lambda.Body as MemberExpression;

    return member.Member.Name;
}

static Func<TEntity, object> MakePropertyGetter<TEntity>(Type entityType, string propertyName)
{
    var parameterExpression = Expression.Parameter(typeof(TEntity), "entity");
    var propertyExpression = Expression.PropertyOrField(parameterExpression, propertyName);

    var lambdaExpression = Expression.Lambda(propertyExpression, parameterExpression);
    var lambdaFunction = lambdaExpression.Compile();

    return (Func<TEntity, object>)lambdaFunction;
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

实体框架代码优先:如何确定运行时用于导航属性的外键属性? 的相关文章

随机推荐

  • 如何在linux中包含python模块?

    我发现了这个 xgoogle python 模块http github com pkrumins xgoogle http github com pkrumins xgoogle 很有意思 我到底应该如何在 Linux 中包含或安装这些文件
  • 单个模块/函数等有超过 1 个文档字符串吗?

    我正在使用 python 3 1 是否可以为单个模块或函数创建超过 1 个文档字符串 我正在创建一个程序 并且打算拥有多个文档字符串 每个文档字符串都有一个类别 我打算向其他人提供该程序 以便他们可以使用它 并且为了让程序员和非程序员都轻松
  • 如何在 Quickblox iOS SDK 中检查会话是否有效或过期?

    我知道 任何会话在向 Quickblox 服务器发出最后一个请求 2 小时前发出 后都会过期 当我创建会话时 我能够找到 QBBaseModule sharedModule tokenExpirationDate但我不确定它是如何工作的以及
  • PHP:通过引用可变长度参数列表?

    是否可以创建一个 PHP 函数 该函数采用可变数量的参数 所有参数均通过引用 它对通过引用接收值数组的函数和将其参数包装在对象中的函数没有帮助 因为我正在研究函数组合和参数绑定 也不要考虑调用时间传递引用 那东西根本不应该存在 PHP 5
  • 如何在laravel中使用shift-jis编码导出csv文件?

    我在用laravel excel https laravel excel com 导出 csv 文件 要导出 代码如下 return Excel download new Export results header test csv Exp
  • 为什么我的关系表会抛出 OutOfMemoryError?

    我正在使用 iReport 构建 jaspersoft 报告 并使用 Fishbowl 作为我的 DBMS 我构建了我的表 在 iReport 中显示我的表是相关的 但由于某种原因它会抛出错误并且不会运行 应该很简单 我正在输入邮政编码 日
  • 使用 PathCollections 的图例

    我正在使用集合绘制圆圈组 但无法生成三个类别的图例 我想 第 1 类 红色圆圈 类别 2 蓝色圆圈 第 3 类 黄色圆圈 import matplotlib import matplotlib pyplot as plt from matp
  • 在我的应用程序中包含 jpeg 插件

    我制作了一个加载 jpeg 文件的 Qt GUI 应用程序 在我安装了 QtSDK 4 7 3 的开发系统 Win7 上 它可以工作 当我将应用程序和一些必需的 dll 如 QtGui4 dll 等 移动到另一个未安装 QtSDK 的系统时
  • 将多个数据帧合并为一个扩展帧

    我有一个数据帧列表 其中每个帧都包含单个系统的相同类型的测量值 例如 system1 file cumSize cumloadTime query1 1 data data1 dat 100000 158 1000 0 4333333 2
  • 动态加载和动态链接的区别?

    例程在被调用之前不会被加载 所有例程都以可重定位加载格式保存在磁盘上 主程序被加载到内存中并被执行 这称为动态链接 为什么这称为动态链接 不应该是动态加载吗 因为在动态加载中调用例程之前不会加载 而在动态链接中 链接会推迟到执行时 此答案假
  • 使用 python 登录 quora

    我尝试使用 python 登录 quora 但它给了我以下错误 urllib2 HTTPError HTTP Error 500 Internal Server Error 到目前为止 这是我的代码 我也在代理后面工作 import url
  • 如何在 FSharp 中对数组的 XML 序列化

    这就是我要找的
  • Git分支没有跟踪信息

    git pull 之后我得到这个输出 There is no tracking information for the current branch Please specify which branch you want to merge
  • 如何在 NSIS 中使用 try catch

    您好 我在安装时在 nsis 安装程序中的几台机器上遇到了奇怪的错误 使用 fontreg nsh 安装字体时给出 无效的 win32 文件句柄 我试过谷歌但没有得到这个问题的答案 现在我正在考虑抑制此消息 那么有什么方法可以抑制此消息 或
  • 数据绑定 Kendo UI 网格后保留展开的行

    这是我第一次使用 Kendo UI 我有一个带有子节点的 Kendo UI 网格 我想在数据绑定后保留扩展的行 现在 在子项中添加一行后 它会折叠起来 我尝试过来自的建议here https stackoverflow com questi
  • 是否可以为 geom_point 和 geom_segment 添加图例?

    我想知道是否可以添加图例geom point and geom segment 从 geom point 我自动获取图例 但是我不知道如何添加图例geom segment 我努力了scale linetype manual但显然它不起作用
  • MVC 是编写 ASP.NET 应用程序的最佳方式吗? [关闭]

    Closed 这个问题是基于意见的 help closed questions 目前不接受答案 更新 我知道没有一种最好的方法可以做所有事情 抱歉没有马上说出来 在数据访问教程的背景下 如果您必须执行他在该教程中所做的项目 如果您必须选择其
  • 如何使用MySQL全文搜索短语而不是使用LIKE

    如何使用 mysql 全文搜索来搜索短语而不是 like SELECT description FROM t WHERE info LIKE Search phrase one OR info LIKE Phrase second OR i
  • 传递 lambda 或异步 lambda 来执行?有权衡吗? [复制]

    这个问题在这里已经有答案了 我试图理解将 lambda 传递到执行 lambda 的异步方法的两种方法的后果 下面的示例总结了这两种方法 在第一种方法中 lambda 本身是异步的 而在第二种方法中则不是 虽然这是一个人为的示例 但我试图确
  • 实体框架代码优先:如何确定运行时用于导航属性的外键属性?

    我有一个实体框架 Code First DbContext 配置了以下实体 在此示例中 Bar 类是 Foo 类的子类 public class Foo public Guid Id get set public virtual IColl