我的应用程序是ASP.NET MVC 5 / SQL Server。
我正在尝试根据数组从列表中选择特定的列:
第一个列表有200列:年龄,性别,.....
select distinct on (customer1.customer_id)
customer1.customer_id,
first_name,
last_name,
email,
purchase.purchase_id,
purchase.purchase_time,
purchase_item.quantity,
purchase_item.total_amount_paid
FROM customer1
LEFT JOIN purchase ON customer1.customer_id = purchase.customer_id
LEFT JOIN purchase_item ON purchase.purchase_id = purchase_item.purchase_id
ORDER BY customer1.customer_id, purchase_time desc;
第二个列表有20列:年龄,性别,......
从视图中,选择要显示的项目:
customer_id | first_name | last_name | email | purchase_id | purchase_time | quantity | total_amount_paid
-------------+------------+-----------+---------------------------+-------------+-------------------------------+----------+-------------------
1 | James | Smith | jamessmith@example.com | 102 | 2019-06-14 20:17:26.759086+00 | 1 | 1995.00
2 | Mary | Johnson | maryjohnson@example.com | 103 | 2019-06-14 20:17:26.759098+00 | 2 | 200.00
3 | John | Williams | johnwilliams@example.com | 104 | 2019-06-14 20:17:26.759109+00 | 1 | 60.00
4 | Patricia | Brown | patriciabrown@example.com | | | |
5 | Michael | Garcia | michaelgarcia@example.com | 105 | 2019-06-14 20:17:26.75912+00 | 1 | 400.00
(5 rows)
为了获得这两个特定的列,我尝试了
var list1 = _reportRepository.ShowMasteView().ToList();
我遇到错误
无法解析符号“包含”
我可以使用以下方法完成
string[] lits2 = showColumn.Where(c => c.Value == true).Select(c=> c.Key).ToArray();
linq中还有更好的方法吗?
答案 0 :(得分:1)
据我了解,您似乎正在尝试提取/选择仅具有所需属性/列的动态对象。
这可以通过构建动态表达式/函数以应用于Select
以下内容基于模型类型和提供的属性来构建表达式
static class DynamicExtensions {
public static IQueryable<dynamic> SelectDynamic<TModel>(this IQueryable<TModel> query, ISet<string> propertyNames) {
var selector = query.BuildSelectorFor(propertyNames);
return query.Select(selector);
}
static Expression<Func<TModel, dynamic>> BuildSelectorFor<TModel>(this IQueryable<TModel> query, ISet<string> propertyNames) {
var modelType = typeof(TModel);
var properties = modelType.GetProperties().Where(p => propertyNames.Contains(p.Name));
// Manually build the expression tree for
// the lambda expression v => new { PropertyName = v.PropertyName, ... }
// (TModel v) =>
var parameter = Expression.Parameter(modelType, "v");
// v.PropertyName
var members = properties.Select(p => Expression.PropertyOrField(parameter, p.Name));
var addMethod = typeof(IDictionary<string, object>).GetMethod(
"Add", new Type[] { typeof(string), typeof(object) });
// { { "PropertyName", v.PropertyName}, ... }
var elementInits = members.Select(m =>
Expression.ElementInit(addMethod, Expression.Constant(m.Member.Name), Expression.Convert(m, typeof(object))));
// new ExpandoObject()
var newExpando = Expression.New(typeof(ExpandoObject));
// new ExpandoObject() { { "PropertyName", v.PropertyName}, ... }
var expando = Expression.ListInit(newExpando, elementInits);
// (TModel v) => new ExpandoObject() { { "PropertyName", v.PropertyName}, ... }
var lambdaExpression = Expression.Lambda<Func<TModel, dynamic>>(expando, parameter);
return lambdaExpression;
}
}
这利用了ExpandoObject
的优势,该成员的成员可以在运行时动态添加和删除。
下面的测试是如何调用上述函数的示例。
[TestMethod]
public void DynamicList() {
var list1 = new List<Person>
{
new Person{ Gender = "Male", Age = 10, FirstName = "Nama1", SampleNumber = 12},
new Person{ Gender = "Male", Age = 12, FirstName = "Nama2", SampleNumber = 13},
new Person{ Gender = "Female", Age = 13, FirstName = "Nama3", SampleNumber = 14},
new Person{ Gender = "Male", Age = 14, FirstName = "Nama4", SampleNumber = 15},
};
var keys = new string[] { "Age", "Gender", };
var nList = list1.AsQueryable().SelectDynamic(new HashSet<string>(keys));
foreach (IDictionary<string, object> row in nList) {
var msg = $"{{ {keys[0]} = {row[keys[0]]}, {keys[1]} = {row[keys[1]]} }}";
Debug.WriteLine(msg);
}
}
并产生以下输出
{ Age = 10, Gender = Male }
{ Age = 12, Gender = Male }
{ Age = 13, Gender = Female }
{ Age = 14, Gender = Male }
动态对象可以在视图中使用,只需调用所需成员即可。
例如,假设您有一个如下模型
public class MyViewModel {
public string MyProperty { get; set; }
public string[] Keys { get; set; }
public List<dynamic> MyDynamicProperty { get; set; }
}
已填充数据并提供给视图的
var list1 = _reportRepository.ShowMasteView();
var keys = new string[] { "Age", "Gender", };
var nList = list1.AsQueryable().SelectDynamic(new HashSet<string>(keys));
var viewModel = new MyViewModel {
MyProperty = "Hello World",
MyDynamicProperty = nList.ToList(),
Keys = keys
};
return View(viewModel);
然后在视图中可以根据需要使用模型,进行强制转换以访问expando对象中的成员。
@model MyViewModel
...
<h2>@Model.MyProperty</h2>
<table>
<tr>
@foreach(string key in Model.Keys) {
<th>@key</th>
}
</tr>
@foreach (IDictionary<string, object> row in Model.MyDynamicProperty) {
<tr>
@foreach(string key in Model.Keys) {
<td>@row[@key]</td>
}
</tr>
}
</table>
答案 1 :(得分:0)
我认为您只需要在列表2上使用“包含”即可。
var nList = list1.Where(t => lits2.Contains(t1));
包含是用于列表的方法。您曾经尝试在字符串上使用它的代码。
答案 2 :(得分:0)
如果您有一个班级的两个清单
public class Person
{
public int id { get; set; }
public string name { get; set; }
}
如果列表如下:
var list1 = new List<Person>
{
new Person{ id = 1, name = "Nama1"},
new Person{ id = 2, name = "Nama2"},
new Person{ id = 3, name = "Nama3"},
new Person{ id = 4, name = "Nama4"},
};
var list2 = new List<Person>
{
new Person{ id = 1, name = "Nama1"},
new Person{ id = 2, name = "Nama2"},
};
您可以通过以下方式进行过滤
var keys = list2.Select(x => x.id).ToList();
var filter1= list1.Where(x => keys.Contains(x.id)).ToList();
var filter2= list1.Where(x => keys.Contains(x.id)).Select(x => new { x.name }).ToList();
var filter3= list1.Select(x => new
{
id = x.id,
name = x.name,
check = keys.Contains(x.id)
}).Where(x => x.check).ToList();
如果您有字符串数组 您可以使用以下代码
相同的数组字符串
var lis1 = new string[] {"name1", "name2","name3" };
var lis2 = new string[] { "name1" };
您可以通过以下方式过滤字符串数组
var items1= lis1.Where(x=>lis2.Contains(x)).ToList();
var items= lis1.Select(x=> new { x, check= lis2.Contains(x) }).Where(x=>x.check == true).ToList();