首页 > 解决方案 > 如何在 EFCore5 中查询属性包实体类型?

问题描述

在 EFCore5 中,隐式表保存为Dictionary<TKey, object>集合,称为Property Bag Entity Types。但是,我无法弄清楚如何使用为 MySQL 编译此类属性包实体类型的 Where() 子句创建 LINQ 查询。

例如,此代码成功检索IQueryable到对中间表的引用(由 EFcore5 的隐式多对多功能生成)给定ISkipNavigation

ISkipNavigation nav = // some many-to-many relationship

IQueryable<Dictionary<string, object>> intermediateTable = 
  context.Set<Dictionary<string, object>>(nav.JoinEntityType.Name);

这段代码成功地检索了中间表中的所有条目:

List<Dictionary<string, object>> joins = await intermediateTable.ToListAsync();

在结果List中,每个Dictionary只有一个键/值(代表行)。

但是,我无法弄清楚如何向.Where()将编译的 LINQ 查询添加子句:

joinTable.Where(d => d.Keys.First() == "foo").ToList();
joinTable.Where(d => d.Keys.Any(k => k == "foo")).ToList();

错误是:

实体类型“MachinePartMachineProfile (Dictionary<string, object>)”上的成员“Keys”的翻译失败。这通常发生在指定成员未映射时。以可翻译的形式重写查询,或通过插入对“AsEnumerable”、“AsAsyncEnumerable”、“ToList”或“ToListAsync”的调用显式切换到客户端评估

出于性能原因,我不希望进行客户端解析(连接表会很大)。

我注意到错误报告的类型是MachinePartMachineProfile (Dictionary<string, object>). 一些调查表明,这些类型是基于静态Model.DefaultPropertyBagType(即 a Dictionary<string, object>)生成的。但尽管盯着 EFCore 代码库,我无法辨别如何正确查询这种默认属性包类型。

我使用 MySQL 作为我的数据库,如果它是相关的。

标签: .net-corelinq-to-sqlentity-framework-corelinq-to-entities

解决方案


您可以直接索引字典,了解列名。

工作示例是:

joinTable.Where(d => d[columnName] == "foo").ToList();

为了完整起见,如果您有一个ISkipNavigation实例,您可以按如下方式推断这些键:

string foreignKey = nav.ForeignKey.Properties.First().GetColumnBaseName();
string localKey = nav.Inverse.ForeignKey.Properties.First().GetColumnBaseName();

推荐阅读