C# 使用';其中';仅当变量有值时,Linq中的语句

C# 使用';其中';仅当变量有值时,Linq中的语句,c#,asp.net,linq,C#,Asp.net,Linq,我有一个正在创建列表的linq查询。如果affiliationID!=0。有什么建议吗 var associations = (from a in ftjent.Associations join ap in ftjent.AssociationProducts on a.AssociationID equals ap.AssociationID where ap.Product.Name == productNam

我有一个正在创建列表的linq查询。如果
affiliationID!=0
。有什么建议吗

var associations = (from a in ftjent.Associations
                    join ap in ftjent.AssociationProducts on a.AssociationID equals ap.AssociationID
                    where ap.Product.Name == productName
                    where a.AffiliationID == affiliationID
                    select new
                        {
                            a.Acronym,
                            a.AssociationID,
                            a.Name
                         }
                     ).Distinct().OrderBy(assoc => assoc.Acronym);

affiliation id
与0进行比较,如果它没有值,则
where
将始终计算为
true
,并且不会进行第二次比较:

var associations = (from a in ftjent.Associations
                join ap in ftjent.AssociationProducts on a.AssociationID equals ap.AssociationID
                where ap.Product.Name == productName
                where (affiliationId == 0) ||  a.AffiliationID == affiliationID
                select new
                    {
                        a.Acronym,
                        a.AssociationID,
                        a.Name
                     }
                 ).Distinct().OrderBy(assoc => assoc.Acronym);

基本上,这些类型的问题(相信我,这是常见的)的通常解决方案是将条件的负数作为“或”,给查询一个替代项,而不是试图仅在条件下附加条件;在这里,要么记录的affiliation id必须与条件匹配,要么条件值没有意义,因此所有记录的完整条件都为true。

像您这样使用查询理解语法很难做到这一点,但是,在使用查询理解语法执行查询之前,您始终可以提取逻辑并创建另一个IQueryable

var products = ftjent.AssociationProducts;
if (affiliationID != null)
    products = products.Where(x => x.AffiliationID = affiliationID);

var associations = (
    from a in ftjent.Associations
    join ap in products on a.AssociationID equals ap.AssociationID
    where ap.Product.Name == productName
    select new
    {
        a.Acronym,
        a.AssociationID,
        a.Name
    }
)
.Distinct()
.OrderBy(assoc => assoc.Acronym);
还有另一个选择:

var associations = (from a in ftjent.Associations
                join ap in ftjent.AssociationProducts on a.AssociationID equals   ap.AssociationID
                where ap.Product.Name == productName               
                select new
                    {
                        a.Acronym,
                        a.AssociationID,
                        a.Name,
                        a.AffiliationID //add AffilationID into the unknown type

                     }
                 ).Distinct().OrderBy(assoc => assoc.Acronym);

if(affilationID != 0)
     associations = associations.Where(a=>a.AffiliationID == affiliationID);
这不是最短的代码,但它明确了流的分离


您可以选择。

虽然我在概念上同意,但实际上,如果源集合是可查询的,并且查询提供程序无法处理表达式树中的多个Where()调用,则这可能会出错。@KeithS:这只是另一种可能的解决方案。正如我所写的,选择取决于OP。事实上,在单个查询中有条件地计算条件几乎是微不足道的。见devundef和我的答案。此外,在OP中,具有AffiliationID的是Association,而不是AssociationProduct。如果您使用Linq to Entities或Linq to SQL,那么您的查询将是次优的,并且不会对or条件使用索引。
var associations = (from a in ftjent.Associations
                join ap in ftjent.AssociationProducts on a.AssociationID equals   ap.AssociationID
                where ap.Product.Name == productName               
                select new
                    {
                        a.Acronym,
                        a.AssociationID,
                        a.Name,
                        a.AffiliationID //add AffilationID into the unknown type

                     }
                 ).Distinct().OrderBy(assoc => assoc.Acronym);

if(affilationID != 0)
     associations = associations.Where(a=>a.AffiliationID == affiliationID);