2012-02-21 21 views
5

Birincisi, ben StackOverflow bu konuda birkaç yazı okudum ama istenilen sonucu alamayan söylemeliyim. Linq SQL iki İfade <Func <T, bool>> birleştirerek ("nerede maddesi") ile ve/veya

beni bağlamı (basitleştirilmiş) açıklayalım: Ben Linq SQL mağazası ve son ziyaretleri müşterilere sorgulamak için kullanıyorum (isteğe bağlı olarak) ödemelerin belirli miktarda sadece bu olsun. Müşteri, ziyaret ve ödeme sınıfları ile bir modelim olduğunu varsayalım.

Yani, Where ifadesi odaklanarak, bu çalışıyorum:

Expression<Func<Entityes.Clients, bool>> filter = null; 

filter = c => 
      c.Visits.Any(v => v.VisitDate > DateTime.Now.Date.AddMonths(-(int)visitsSince)); 


if (minPayment.HasValue && minPayment.Value > 0) 
{ 
    filter.And(
       c => c.Payments.Sum(p => p.Quantity) > minPayment.Value); 
} 

filter.And yöntemdir sen tanımını görebilirsiniz altında, bu forumda önerilen uzatma yöntemi:

public static Expression<Func<T, bool>> And<T>(this Expression<Func<T, bool>> expression1, 
              Expression<Func<T, bool>> expression2) 
{ 
    InvocationExpression invokedExpression = 
     Expression.Invoke(expression2, expression1.Parameters.Cast<Expression>()); 

    return Expression.Lambda<Func<T, bool>> 
     (Expression.And(expression1.Body, invokedExpression), expression1.Parameters); 
} 
beklenen ve sonuçlar ödeme tutarı tarafından filtre edilmez olarak

Ancak bu benim için çalışmaz. Ancak

filter = c => 
      c.Visits.Any(v => v.VisitDate > DateTime.Now.Date.AddMonths(-(int)visitsSince))) 
      && c => c.Payments.Sum(p => p.Quantity) > minPayment.Value; 

ben ihtiyacım olan biraz daha karmaşık senaryolar zorunda çünkü son kodu kullanmak istemiyorsanız: Bu kod çalışıyor çünkü veri veya linq-to-sql modeli ile hiçbir hata var Filtre ifadesini, her parçanın bir 've/veya' kombinasyonu ile adım adım oluşturun.

PD: Ben-SQL Linq ve yakında Varlık Framework, yakında StackOverflow topluma faydalı olması ümit öğrenmeye çalışıyorum bir "ADO.Net DataSets" adamım.

+3

P.S., sen ('&&'), mantıksal ve ifade oluşturmak için 'Expression.AndAlso() 'yöntemi kullanarak olmalıdır. Expression.And(), bit ve AND ifadesini oluşturur ('&'). –

cevap

3

Herhangi bir şey için ing And sonucunu atama değildir.

Kuralların ilgili kısmı aşağıdaki gibi okumalısınız varsayalım:

if (minPayment.HasValue && minPayment.Value > 0) 
{ 
    filter = filter.And(
      c => c.Payments.Sum(p => p.Quantity) > minPayment.Value); 
} 

şey olduğunu sizin (veya belirtildiği gibi SO var) And fonksiyonu döner iki ifadenin bağlaç içeren ifade. Üzerinde çalıştırılan nesneyi değiştirmez.

+0

ouch ... teşekkürler! –

+0

@FranCD Rica ederim. Bu arada, sorunuzu orijinal versiyona geri çekmek için özgürlüğümü aldım, böylece daha fazla ziyaretçi asıl orijinal kodun ne olduğunu gördü. Aksi takdirde, aşağıdaki cevaplar mantıklı değildir. – Krizz

0

kontrol dışarı LinqKit ve PredicateBuilder sınıf var:

filter.And(c => c.Payments.Sum(p => p.Quantity) > minPayment.Value); 

And yöntemi şey atanmamış olan başka temsilci verir: http://www.albahari.com/nutshell/predicatebuilder.aspx

+0

Kullandığım uygulama PredicateBuilder sınıfından geliyor ve çalışmıyor ... Hata nerede? –

+0

@FranCD kullanımınızda bir hata var, cevabımı gör. – Krizz

1

sorun bu çizgidir. Bu deneyin:

filter = filter.And(c => c.Payments.Sum(p => p.Quantity) > minPayment.Value); 

Sadece netleştirmek için And yeni ifade oluşturmak için kendi mantığı iki ifadeler alır ve birleştiren bir yöntemdir. Üzerinde çalıştırılan ifadeyi değiştirmez, ancak yeni ifadeyi bir dönüş değeri olarak döndürür. Kodunuzdaki Eğer filter.And(...) aradığınız ama dönüş değeri, hiçbir şey yapmıyor Yani, bu yüzden filter hala orijinal lambda ifade başvurur.