2017-09-19 13 views
1
var entity = 
    from document in db.Context.DocumentEntity 
    join product in db.Context.ProductEntity on document.ProductId equals product.Id 
    join partner in db.Context.PartnerEntity on product.PartnerId equals partner.Id 
    select new 
    { 
     document, 
     product, 
     partner 
    } into t1 
    where request.PartnerFilter.Contains(t1.partner.Name) 
    group t1 by t1.document.Date into rp 
    select new 
    { 
     PartnerName = rp.FirstOrDefault().partner.Name, 
     Date = rp.FirstOrDefault().document.Date, 
     Income = rp.Sum(x => x.document.Income), 
     Click= rp.Sum(x => x.document.Click) 
    }; 

result = ToDataTable(entity.OrderByDescending(d=>d.Date).ToList()); 


public static DataTable ToDataTable<T>(List<T> items) 
{ 
    DataTable dataTable = new DataTable(typeof(T).Name); 

    PropertyInfo[] Props = typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance); 
    foreach (PropertyInfo prop in Props) 
    { 
    var type = (prop.PropertyType.IsGenericType && prop.PropertyType.GetGenericTypeDefinition() == typeof(Nullable<>) ? Nullable.GetUnderlyingType(prop.PropertyType) : prop.PropertyType); 
    dataTable.Columns.Add(prop.Name, type); 
    } 
    foreach (T item in items) 
    { 
    var values = new object[Props.Length]; 
    for (int i = 0; i < Props.Length; i++) 
    { 
     values[i] = Props[i].GetValue(item, null); 
    } 
    dataTable.Rows.Add(values); 
    } 
return dataTable; 

}- 文がSystem.NotSupported例外

問題は、where句であるがスローされます。 request.PartnerFilterは文字列配列であり、nullの可能性があります。 partner.Nameが含まれているかどうかを確認する必要があります。 SQLの場所の種類。 end entity.ToList()では、System.NotSupported Exceptionをスローします。どのようにフィルタリングすることができますか? Entity Frameworkのは、Requestオブジェクトをどのように処理するかわからないため

答えて

4

あなたはEFクエリ式ツリー内Containsを使用する場合は、変数がnullでないことを確認する必要があります。そして、クエリの外部で(条件を適用する必要がある場合は)それを実行する必要があります。例えば

var partnerFilter = request.PartnerFilter ?? Enumerable.Empty<string>(); 
bool applyPartnerFilter = partnerFilter.Any(); 

var entity = 
    ... 
    where (!applyPartnerFilter || partnerFilter.Contains(t1.partner.Name)) 
    ... 

しかし、私の意見では、たとえば、クエリの外の任意のフィルタを適用するためにはるかに良いでしょう:

var partners = db.Context.PartnerEntity.AsQueryable(); 
if (request.PartnerFilter != null && request.PartnerFilter.Any()) 
    partners = partners.Where(partner => request.PartnerFilter.Contains(partner.Name)); 

var entity = 
... 
join partner in partners on product.PartnerId equals partner.Id 
... 

(なしwhere

+0

素晴らしいです。問題を解決し、EFでContainsを使用する方法を学びました。 – Jude

2

代わりにナビゲーションプロパティを使用し、それはまた、

string[] strArray=request.PartnerFilter; 

var entity = 
from document in db.Context.DocumentEntity 
join product in db.Context.ProductEntity on document.ProductId equals product.Id 
join partner in db.Context.PartnerEntity on product.PartnerId equals partner.Id 
select new 
{ 
    document, 
    product, 
    partner 
} into t1 
//Check if null 
where strArray!=null && strArray.Any() && strArray.Contains(t1.partner.Name) 
group t1 by t1.document.Date into rp 
select new 
{ 
    PartnerName = rp.FirstOrDefault().partner.Name, 
    Date = rp.FirstOrDefault().document.Date, 
    Income = rp.Sum(x => x.document.Income), 
    Click= rp.Sum(x => x.document.Click) 
}; 

などの文字列、文字列配列を扱うことができ、式のうち、この要求の一部を取ります結合の数

+0

同じことが起こりました。何の違いもありませんでした。ヌルチェックで問題が発生する可能性があります。私は旋盤作業員を使用しました。 – Jude

+0

答えが更新されました。plsもう一度やり直してください – Tuco

+0

私はstrArrayに項目を追加しました。どこの文を条件に入れるか(キーワードを含む) – Jude

1

ContainsのSQL WHERE IN()節を使用します。あなたの唯一の問題は、可能なヌル例外です。

アレイが空の場合どうなりますか?あなたはすべての価値を持っていますか?クエリとして構文

var selected = from document in Document 
       where new[] {"Paul", "Peter"}.Contains(document.UserName) 
       select document 

、IN - - 方法と​​して構文

string[] partnerNames = request.PartnerFilter; 

var entity = 
    from document in db.Context.DocumentEntity 
    join product in db.Context.ProductEntity on document.ProductId equals product.Id 
    join partner in db.Context.PartnerEntity on product.PartnerId equals partner.Id 
    select new 
    { 
     document, 
     product, 
     partner 
    } into t1 
    where partnerNames?.Contains(t1.partner.Name) ?? true 
    group t1 by t1.document.Date into rp 
    select new 
    { 
     PartnerName = rp.FirstOrDefault().partner.Name, 
     Date = rp.FirstOrDefault().document.Date, 
     Income = rp.Sum(x => x.document.Income), 
     Click= rp.Sum(x => x.document.Click) 
    }; 

WHEREの場合:配列がnullの場合

はこれを試してみてくださいfalse

にそうtrueを使用します
var selected = Document 
       .Where(d => new[] ["Paul","Peter"}.Contains(d.UserName)) 
+0

'request.PartnerFilter!= null? request.PartnerFilter.Contains(t1.partner.Name):true'を返します。エンティティ.ToList()VSウォッチステートメントでも同じエラーがスローされます。デバッグを続けると、次のようになります。 'System.String []'型のヌル定数値を作成できません。このコンテキストでは、エンティティタイプ、列挙型、またはプリミティブ型のみがサポートされています – Jude

+0

'.Any()' checkで初期化された空のリストを使用できますか? – cSteusloff

+0

私はこれを試しました: 'List list = new List (); list.Add( ""); 'と' where list.Any() 'です。それは働いています – Jude