3

SQL テーブルから作成された linq オブジェクトに計算列を追加しようとしています。データベースでこれを行うことはできません。

public partial class History_SHIP
{
    public Expression<Func<DateTime>> TransactionDateTime
    {
        get
        {
            return () => TransactionDate.AddMinutes(SqlMethods.DateDiffMinute(TransactionTime, new DateTime(1900, 1, 1)));
        }
    }
}

以下のようなwhere句の一部として使用できるようにしたいと思います。

where sh.TransactionDateTime >= startDate

startDateであり、DateTimeshHistory_SHIPオブジェクトです。

また、selectステートメントでも簡単に使用できるようにしたいと思います( を実行する別のプロパティを作成できてうれしいですTranslationDateTime.Compile()())。

where 句で私が抱えている問題は、 a の LHSExpression<Func<DateTime>>と RHS が aDateTimeであるため、不平を言うことです。


このリンクhttp://www.codeproject.com/Articles/32968/QueryMap-Custom-translation-of-LINQ-expressionsを見たことがありますが、この 1 つのプロパティに追加の依存関係は必要ありません (とにかく今のところ)。

4

2 に答える 2

1

はい、さまざまな理由から、それは幸せではありません。

  • まず、LINQ インタープリターはそれを直接処理できます-助けが必要です
  • 第二に、実装されたプロパティは に関連するものを返しますthisが、実際にはParameterExpression(別名sh)に関連するものが必要です。

最も簡単な方法は、おそらく、これを便利にフィルタリングできる拡張メソッドを追加することです。たとえば、次のように書き換えますExpression

var filtered = source.WhereTransactionDate(when => when > DateTime.Now);

実装あり:

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);
        }
    }
}

これが行うことは、2 つの式ツリーをマージすることです。

x => x.TransactionDate.AddMinutes(SqlMethods.DateDiffMinute(
                     x.TransactionTime, new DateTime(1900, 1, 1)))

と:

when => when > DateTime.Now

すべてを最初の式の本体に置き換えますwhen(および最初の式のパラメーターを使用します)。つまり、作成します。

x => x.TransactionDate.AddMinutes(SqlMethods.DateDiffMinute(
           x.TransactionTime, new DateTime(1900, 1, 1))) > DateTime.Now;
于 2012-10-10T08:54:13.457 に答える
0

どうですか...

where sh.TransactionDateTime.Compile().Invoke() >= startDate 
于 2012-10-10T08:45:40.660 に答える