2017-09-19 86 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; 

}LINQ到實體 - 在聲明中拋出System.NotSupported異常

的問題是在where子句。 request.PartnerFilter是一個字符串數組,可能爲空。我需要檢查是否包含partner.Name。種類的SQL在哪裏。最後entity.ToList()拋出System.NotSupported異常。我怎樣才能完成過濾?

回答

4

如果你想使用Contains的EF查詢表達式樹裏面,你需要確保該變量不爲空。並且您需要在查詢外執行此操作(以及需要應用的條件)。

例如:

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

同樣發生。沒有任何區別。問題可能是空檢查。我使用turnery操作符。 – Jude

+0

已更新的答案,請再試一次 – Tuco

+0

我已經添加了一個項目到strArray,它的工作,而如果它仍然是空的。任何方式把整個where語句放入條件(包括關鍵字) – Jude

1

您使用SQL WHERE IN()子句與Contains正確。你唯一的問題是可能的空例外。

如果數組爲空,會發生什麼?你想擁有所有的價值嗎?使用true如果數組爲空,否則false

試試這個:

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

凡在 - 作爲查詢語法

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

凡在 - 作爲方法的語法

var selected = Document 
       .Where(d => new[] ["Paul","Peter"}.Contains(d.UserName)) 
+0

我做了'request.PartnerFilter!= null? request.PartnerFilter.Contains(t1.partner.Name):true'。 VS監視語句中的entity.ToList()仍然會引發相同的錯誤。如果我繼續調試,結果如下:無法創建類型爲'System.String []'的空常量值。在這種情況下,僅支持實體類型,枚舉類型或基本類型 – Jude

+0

您可以使用'.Any()'檢查來初始化空列表嗎? – cSteusloff

+0

我試過這個:'List list = new List (); list.Add(「」);'和'where list.Any()'。它正在工作 – Jude