使用 Linq to Entities (EF6) 动态选择列名
Posted
技术标签:
【中文标题】使用 Linq to Entities (EF6) 动态选择列名【英文标题】:Dynamically select column name using Linq to Entities (EF6) 【发布时间】:2015-09-26 22:13:27 【问题描述】:我想封装使用EF6时的常见场景。 这是一个例子:
public class StringRequest : DbRequestProperty
public string Name get; set;
public bool? ExactMatch get; set;
protected override bool IsValid()
return !string.IsNullOrWhiteSpace(Name);
private bool RequestExactMatch()
return ExactMatch.HasValue && ExactMatch.Value;
protected override IQueryable<T> Execute<T>(IQueryable<T> original, string propertyName)
return RequestExactMatch()
? original.Where(o => GetProperty<string>(o, propertyName) == Name)
: original.Where(o => GetProperty<string>(o, propertyName).Contains(Name));
但 GetProperty 无法转换为查询。 所以我正在考虑使用“propertyName”动态选择列。
protected override IQueryable<T> Execute<T>(IQueryable<T> original, string propertyName)
return RequestExactMatch()
? original.Where(o => GetColumnByName<string>(propertyName) == Name)
: original.Where(o => GetColumnByName<string>(propertyName).Contains(Name));
这可能吗? 提前致谢。
【问题讨论】:
【参考方案1】:您可以像这样使用Expression 类动态创建Expression<Func<T, bool>>
:
protected override IQueryable<T> Execute<T>(IQueryable<T> original, string propertyName)
var parameter = Expression.Parameter(typeof(T));
var property = Expression.PropertyOrField(parameter, propertyName);
var constant = Expression.Constant(Name);
Expression predicate;
if(RequestExactMatch())
predicate = Expression.Equal(property, constant);
else
predicate = Expression.Call(property, "Contains", null, constant);
var lambda = Expression.Lambda<Func<T, bool>>(predicate, parameter);
return original.Where(lambda);
【讨论】:
谢谢先生。它工作得很好。你帮我重构了大量重复的代码。 @Chorinator - 我很高兴能帮上忙! 日期怎么样。有没有办法截断数据库部分的时间部分,所以我最终只比较日期?我试过使用 Convert 和 Cast 但我得到一个异常说 System.Date 上不存在这些函数 @Chorinator - 我相信有办法,但问另一个问题 我已经找到了一种方法,基于这篇文章***.com/a/1759993/261549以上是关于使用 Linq to Entities (EF6) 动态选择列名的主要内容,如果未能解决你的问题,请参考以下文章
LINQ to Entities 不支持 LINQ 表达式节点类型“Invoke”
如果存在-UPDATE-else-INSERT 与 Linq-to-Entities?