Sub GetFlows()
Dim rng As Range
Dim row As Range
Dim cell As Range
Dim dem1 As String
Dim WhereCell As Range
Dim ws As Excel.Worksheet
Dim iIndex As Integer
Dim valueRng As Range
Dim x As Long
Dim y As Long
Set rng = Range("A9:A200") ' should specify a sheet here, presumably Summary?
For Each ws In ThisWorkbook.Worksheets
If ws.Name <> "summary" Then
For x = 1 To rng.Rows.Count
dem1 = rng.Cells(x).Value
If dem1 <> vbNullString Then
Set WhereCell = ws.Range("A9:A200").Find(dem1, lookat:=xlPart)
If Not WhereCell Is Nothing Then
Workbooks("GetFilenames v2.xlsm").Worksheets(dem1).Range("A1").CurrentRegion.Copy
WhereCell.Offset(, 2).PasteSpecial Paste:=xlPasteValues
End If
End If
Next x
End If
Next ws
End Sub
}
问题在于where子句。 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;
是一个字符串数组,可能为null。我需要检查其中是否包含request.PartnerFilter
。 Sql Where-In的种类。最后,entity.ToList()抛出System.NotSupported Exception。如何完成过滤?
答案 0 :(得分: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
)
答案 1 :(得分:2)
将此请求部分排除在等式之外,因为实体框架不知道如何处理Request对象,它可以处理字符串,字符串数组等。
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)
};
此外,使用导航属性而不是连接
答案 2 :(得分:1)
您使用SQL WHERE IN ()
子句与Contains
正确无误。您唯一的问题是可能的null异常。
如果数组为空,会发生什么?你想拥有所有价值观吗?如果数组为空,请使用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)
};
WHERE IN - 作为查询语法
var selected = from document in Document
where new[] {"Paul", "Peter"}.Contains(document.UserName)
select document
WHERE IN - 作为方法语法
var selected = Document
.Where(d => new[] ["Paul","Peter"}.Contains(d.UserName))