[英]Using a method returning an expression in LINQ-To-SQL
I'm trying to add a computed column to my linq object created from an SQL table. 我正在尝试将计算列添加到从SQL表创建的linq对象中。 I can't do this in the database. 我不能在数据库中这样做。
public partial class History_SHIP
{
public Expression<Func<DateTime>> TransactionDateTime
{
get
{
return () => TransactionDate.AddMinutes(SqlMethods.DateDiffMinute(TransactionTime, new DateTime(1900, 1, 1)));
}
}
}
I'd like to be able to use it as part of a where clause like below: 我希望能够将它作为where子句的一部分使用,如下所示:
where sh.TransactionDateTime >= startDate
startDate
is a DateTime
and sh
is my History_SHIP
object. startDate
是一个DateTime
, sh
是我的History_SHIP
对象。
I'd also like to be able to easily use it in a select statement too (I'm happy to create another property that does a TranslationDateTime.Compile()()
). 我也希望能够在select语句中轻松使用它(我很乐意创建另一个执行TranslationDateTime.Compile()()
属性。
The problem I have with the where clause is that the LHS in a Expression<Func<DateTime>>
and the RHS is a DateTime
, so it complains. 我对where子句的问题是Expression<Func<DateTime>>
中的LHS和RHS是DateTime
,所以它抱怨。
I have seen this link http://www.codeproject.com/Articles/32968/QueryMap-Custom-translation-of-LINQ-expressions but don't want additional dependencies for this one property (for now anyway). 我已经看到这个链接http://www.codeproject.com/Articles/32968/QueryMap-Custom-translation-of-LINQ-expressions但是不希望这个属性有其他依赖关系(现在无论如何)。
Yes, that isn't going to be happy, for various reasons; 是的,出于各种原因,这不会令人满意;
this
, but in reality we need something in relation to a ParameterExpression
(aka sh
) 其次,实现的属性返回与this
,但实际上我们需要与ParameterExpression
(aka sh
)相关的东西 The easiest thing to do is probably to add an extension method that lets you filter on this conveniently, for example by re-writing an Expression
: 最简单的方法是添加一个扩展方法,让您可以方便地对此进行过滤,例如通过重写Expression
:
var filtered = source.WhereTransactionDate(when => when > DateTime.Now);
with implementation: 实施:
static class Utils
{
static readonly Expression<Func<Foo, DateTime>> tranDateTime =
x => x.TransactionDate.AddMinutes(SqlMethods.DateDiffMinute(
x.TransactionTime, new DateTime(1900, 1, 1)));
public static IQueryable<Foo> WhereTransactionDate(
this IQueryable<Foo> source,
Expression<Func<DateTime, bool>> predicate)
{
var visited = SwapVisitor.Swap(predicate.Body,
predicate.Parameters.Single(), tranDateTime.Body);
var lambda = Expression.Lambda<Func<Foo, bool>>(
visited, tranDateTime.Parameters);
return source.Where(lambda);
}
class SwapVisitor : ExpressionVisitor
{
public static Expression Swap(Expression source,
Expression from, Expression to)
{
return new SwapVisitor(from, to).Visit(source);
}
private SwapVisitor(Expression from, Expression to)
{
this.from = from;
this.to = to;
}
readonly Expression from, to;
public override Expression Visit(Expression node)
{
return node == from ? to : base.Visit(node);
}
}
}
What this does is merge two expression-trees, ie 这样做是合并两个表达式树,即
x => x.TransactionDate.AddMinutes(SqlMethods.DateDiffMinute(
x.TransactionTime, new DateTime(1900, 1, 1)))
and: 和:
when => when > DateTime.Now
replacing all when
with the body from the first expression (and using the parameter from the first expression) ie creating 更换所有when
与所述主体从所述第一表达(以及使用来自所述第一表达的参数),即产生
x => x.TransactionDate.AddMinutes(SqlMethods.DateDiffMinute(
x.TransactionTime, new DateTime(1900, 1, 1))) > DateTime.Now;
怎么样...
where sh.TransactionDateTime.Compile().Invoke() >= startDate
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.