如何在 EF 中使用强类型 ID?
Posted
技术标签:
【中文标题】如何在 EF 中使用强类型 ID?【英文标题】:How to use strongly typed id in in EF? 【发布时间】:2021-11-22 17:41:13 【问题描述】:我有原始的痴迷类 EmailAddress
已覆盖 ToString()
:
public class EmailAddress
private string _value;
public EmailAddress(string value)
_value = value;
public override string ToString()
return _value;
我的域模型Customer
看起来像:
public class Customer
public EmailAddress EmailAddress get; set;
public string FullName get; set;
我已经在 FluentApi 中为EmailAddress
配置了转换:
modelBuilder.Entity<Customer>().Property(x => x.EmailAddress)
.HasConversion(
x => x.ToString(),
x => new EmailAddress(x));
我也有通用存储库模式,当我想过滤数据时:
public List<Customer> GetCustomers(GetCustomersQuery queryParameters)
IQueryable<Customer> queryCustomers = _customerContext.GetAll();
return queryCustomers.Where(x =>
x.EmailAddress.ToString()
.Contains(queryParameters.Email)).ToList();
我有一个错误:
无法翻译 LINQ 表达式
DbSet<Customer>().Where(t => t.EmailAddress.ToString()
。额外的 信息:方法object.ToString
的翻译失败。
我试过 EF 6.4 你有什么解决方法吗?
【问题讨论】:
为什么?为什么要使您的域过于复杂?您可以将 setter 内部化并引入一个公共方法/类来清理电子邮件。保持实体定义简单且实用。 【参考方案1】:对于真正有动力,不怕复杂领域的人,我找到了解决方案
public class EmailAddress
private string _value;
public static explicit operator string(EmailAddress emailAddress) => emailAddress._value;
public EmailAddress(string value)
_value = value;
public override string ToString()
return _value;
查询是
queryCustomers.Where(x =>
((string)x.EmailAddress)
.Contains(queryParameters.Email)).ToList();
此查询正在服务器端执行。
【讨论】:
请发布您的查询生成的 SQL,我很好奇。 去掉class EmailAddress
直接使用字符串,你的问题就迎刃而解了。
@Robert 我很想看看生成了什么 SQL,仍然怀疑这不是客户端评估。以上是关于如何在 EF 中使用强类型 ID?的主要内容,如果未能解决你的问题,请参考以下文章
EF CTP5 - 强类型急切加载 - 如何包含嵌套导航属性?
我开发的开源项目,让.NET7中的EFCore更轻松地使用强类型Id