DDD仓储中如何对值对象执行Contains过滤查询?
解决DDD值对象Contains方法EF Core查询翻译失败问题
问题原因
EF Core无法将自定义值对象HolidayTitle的Contains方法转换为对应的SQL语句,导致查询无法执行。
解决方案
方案1:直接访问值对象的Value属性
修改查询条件,直接使用HolidayTitle的Value属性调用Contains,EF Core可以识别字符串的Contains并生成正确的SQL:
if (!string.IsNullOrEmpty(param.Title)) query = query.Where(x => x.Title.Value.Contains(param.Title));
注意:确保EF Core已正确映射
HolidayTitle到数据库字符串列,通常在实体配置中通过值转换实现:modelBuilder.Entity<Holiday>() .Property(h => h.Title) .HasConversion( title => title.Value, value => HolidayTitle.GetInstance(value));
方案2:利用隐式转换
由于HolidayTitle定义了到string的隐式转换,可将值对象转为字符串后调用Contains:
if (!string.IsNullOrEmpty(param.Title)) query = query.Where(x => ((string)x.Title).Contains(param.Title));
EF Core会自动将隐式转换解析为访问Value属性,生成对应的SQL LIKE查询。
方案3:自定义EF Core方法映射(保持领域封装)
如果不想直接暴露Value属性,可通过EF Core的自定义函数映射,将HolidayTitle.Contains映射为SQL的LIKE操作:
- 在你的DbContext中定义静态方法:
public static bool HolidayTitleContains(HolidayTitle title, string str) { return title.Contains(str); }
- 在
OnModelCreating中配置方法映射:
modelBuilder.HasDbFunction(typeof(YourDbContext).GetMethod(nameof(HolidayTitleContains))) .HasTranslation(args => EF.Functions.Like(args[0].Property("Value"), $"%{args[1]}%"));
- 查询时使用该静态方法:
if (!string.IsNullOrEmpty(param.Title)) query = query.Where(x => YourDbContext.HolidayTitleContains(x.Title, param.Title));
内容的提问来源于stack exchange,提问作者Yaser Nouri
相关产品推荐
相关产品推荐

