c#方法链vs linq查询

时间:2014-10-23 17:36:55

标签: c# linq entity-framework method-chaining

我在方法链中写了一个查询:

var query = finnEntities.FINN_TRANSACTION_VIEW.Where(
        x => x.CREDIT_ID == model.CodeId 
        || x.DEBTOR_ID == model.CodeId 
        && (x.TRANSACTION_DATE>= model.DateTimeFrom.Date 
            && x.TRANSACTION_DATE <= model.DateTimeTo.Date) 
        && x.CURRENCY_TYPE_ID == model.CurrencyId);

我使用linq表达式编写了相同的查询:

var queryTransaction = 
    from t in finnEntities.FINN_TRANSACTION_VIEW
    where (t.CREDIT_ID == model.CodeId 
        || t.DEBTOR_ID == model.CodeId) 
        && (t.TRANSACTION_DATE >= model.DateTimeFrom 
            && t.TRANSACTION_DATE <= model.DateTimeTo) 
        && t.CURRENCY_TYPE_ID == model.CurrencyId
    select new { t };

但它们有不同的输出,第二个返回正确的结果

2 个答案:

答案 0 :(得分:1)

如果你看两个查询,你会发现你有

    在第二个查询中,{li>

    ()t.CREDIT_ID == model.CodeId || t.DEBTOR_ID == model.CodeId左右,并且您在第一个查询中没有它们。这会改变where子句中的操作顺序。

  1. 在第一个中添加.Date,截断到当天,但不是第二个。

  2. 假设第二个查询确实返回了正确的结果,您可以将第一个更改为:

    var query = finnEntities.FINN_TRANSACTION_VIEW.Where(x =>
        (x.CREDIT_ID == model.CodeId || x.DEBTOR_ID == model.CodeId)
        && x.TRANSACTION_DATE>= model.DateTimeFrom
        && x.TRANSACTION_DATE <= model.DateTimeTo
        && x.CURRENCY_TYPE_ID == model.CurrencyId);
    

    在上文中,我还删除了查询的多个部分周围的冗余()

答案 1 :(得分:0)

您的括号不同。只是比较你写条件的方式,你应该注意括号和日期差异。

x.CREDIT_ID == model.CodeId || x.DEBTOR_ID == model.CodeId && (x.TRANSACTION_DATE>= model.DateTimeFrom.Date && x.TRANSACTION_DATE <= model.DateTimeTo.Date) && x.CURRENCY_TYPE_ID == model.CurrencyId


(t.CREDIT_ID == model.CodeId || t.DEBTOR_ID == model.CodeId) && (t.TRANSACTION_DATE >= model.DateTimeFrom && t.TRANSACTION_DATE <= model.DateTimeTo) && t.CURRENCY_TYPE_ID == model.CurrencyId

同样,为了便于阅读,将更复杂的条件放入这样的函数中是个好主意:

bool _iHaveAMeaningfulName(Model model, WhatEver t)
{
    return (t.CREDIT_ID == model.CodeId || t.DEBTOR_ID == model.CodeId) && 
           (t.TRANSACTION_DATE >= model.DateTimeFrom && t.TRANSACTION_DATE <= model.DateTimeTo) && 
            t.CURRENCY_TYPE_ID == model.CurrencyId
}

然后您可以更轻松地重复使用它,并且还可以更好地将Linq-Queries与方法链进行比较:

// Method-Chain
finnEntities.FINN_TRANSACTION_VIEW.Where(t => _iHaveAMeaningfulName(model,t));

// query
from f in finnEntities.FINN_TRANSACTION_VIEW
where _iHaveAMeaningfulName(f,model)
select new { f }; // this returns an annonymous type

你还应该注意到你的查询返回了一个匿名类型,因为你写了:

select new { f };

为了与方法链等效,您需要删除新的{}

select f;