use*_*468 9 c# linq generics reflection c#-4.0
我如何在linq中将实体类型作为参数传递?
例如,该方法将接收实体名称值作为字符串,我想将实体名称传递给下面的linq查询.是否可以使linq查询通用?
public ActionResult EntityRecords(string entityTypeName)
{
var entityResults = context.<EntityType>.Tolist();
return View(entityResults);
}
Run Code Online (Sandbox Code Playgroud)
我想将实体类型作为参数传递并返回所有属性值.
此外,是否可以根据某些属性过滤结果?
假设你的context班级是这样的:
public class MyContext : DbContext
{
public DbSet<Entity1> Entity1 { get; set; }
public DbSet<Entity2> Entity2 { get; set; }
// and so on ...
}
Run Code Online (Sandbox Code Playgroud)
最简单的解决方案是编写如下所示的方法
private List<object> Selector(string entityTypeName)
{
if (entityTypeName == "Entity1")
return context.Entity1.ToList();
if (entityTypeName == "Entity2")
return context.Entity2.ToList()
// and so on
// you may add a custom message here, like "Unknown type"
throw new Exception();
}
Run Code Online (Sandbox Code Playgroud)
但我们不想对这些东西进行硬编码,所以让我们Selector动态创建Linq.Expressions
Func在控制器中定义一个字段:
private readonly Func<string, List<object>> selector;
Run Code Online (Sandbox Code Playgroud)
现在您可以为此成员创建一个工厂:
private Func<string, List<object>> SelectByType()
{
var myContext = Expression.Constant(context);
var entityTypeName = Expression.Parameter(typeof(string), "entityTypeName");
var label = Expression.Label(typeof(List<object>));
var body = Expression.Block(typeof(MyContext).GetProperties()
.Where(p => typeof(IQueryable).IsAssignableFrom(p.PropertyType) && p.PropertyType.IsGenericType)
.ToDictionary(
k => Expression.Constant(k.PropertyType.GetGenericArguments().First().Name),
v => Expression.Call(typeof(Enumerable), "ToList", new[] {typeof(object)}, Expression.Property(myContext, v.Name))
)
.Select(kv =>
Expression.IfThen(Expression.Equal(kv.Key, entityTypeName),
Expression.Return(label, kv.Value))
)
.Concat(new Expression[]
{
Expression.Throw(Expression.New(typeof(Exception))),
Expression.Label(label, Expression.Constant(null, typeof(List<object>))),
})
);
var lambda = Expression.Lambda<Func<string, List<object>>>(body, entityTypeName);
return lambda.Compile();
}
Run Code Online (Sandbox Code Playgroud)
并Func用它赋值(构造函数中的某个位置)
selector = SelectByType();
Run Code Online (Sandbox Code Playgroud)
现在你可以像这样使用它
public ActionResult EntityRecords(string entityTypeName)
{
var entityResults = selector(entityTypeName);
return View(entityResults);
}
Run Code Online (Sandbox Code Playgroud)