c# - 使用 HasKey 查找实体而不显式指定查询中的所有键
问题描述
使用 EF,您可以指定一个复合键,HasKey
所以我想有一种方法可以使用实体作为某些 API 的参数来在数据库中找到它,但我不知道如何。
我希望使用的Find
API 需要一组键值,但我正在寻找的是这样的:
var setting = new Setting { Name = "WindowSize" };
setting = context.Find(setting);
由于我可以通过指定所有键,modelBuilder.Entity<Setting>.HasKey(s => new { s.Name })
因此必须有一种方法可以重用它。你知道一个 API 或让它以这种方式工作的技巧吗?
该Setting
模型是可交换的,并且可能具有其他关键列。我希望能够自动找到它,而不必两次指定条件。
这意味着可以有:
modelBuilder.Entity<Setting>.HasKey(s => new { s.Name, s.Version })
我希望这个定义被重用于查询,而我不必说Find("name", "version")
等等。但是context.SomeAPI(settingWithTwoKeys)
。
解决方案
EF Core 中没有任何内置功能可以做到这一点,但编写一个.Find
可以为您完成的扩展方法并不难。这是执行此操作的示例方法(未经测试)。
(注意:当您调用此方法时,您可以依赖通用参数推断,并且只传入实体本身 - 就像context.Find(settingWithTwoKeys)
)。
public static TEntity Find<TEntity>(this DbContext context, TEntity keyObject)
{
var entityType = context.Model.FindEntityType(typeof(TEntity));
var pk = entityType.FindPrimaryKey();
var keyArgs = new List<object>();
foreach(var pkProperty in pk.Properties)
{
var propValueInKeyObject = pkProperty.PropertyInfo.GetValue(keyObject);
keyArgs.Add(propValueInKeyObject);
}
return context.Find<TEntity>(keyArgs);
}
你的第二个问题 - 这是HasKey
为了什么。只要您的数据库实现与 EF 约定不匹配,您就可以使用它。您的Setting
实体就是一个很好的例子。EF 中没有允许它自动识别Name
并且Version
是 PK 的约定。您需要HasKey
在模型构建器中使用来告诉它。
推荐阅读
- php - 如何在 cakephp 3 中操作树形菜单的子项?
- python - 试图用 python 做一个语音识别程序,但程序似乎没有听到我的声音
- python - 限制在python中作为输入接受的整数值的域
- javascript - 输入密码类型仅在 Safari 上阻止退格键
- python - 如何在类的构造函数中定义 *args
- wordpress - 无法将发布图像居中
- javascript - 在 React 函数式组件中声明静态变量的最佳方式是什么?
- grav - 理解 Grav 中的菜单和模块页面
- r - 从 dplyr 管道中的当前观察中减去特定数字
- swift - 使用 isHidden = true 隐藏横幅广告