[英]Entity Framework - LINQ - Dynamic Column Names
我知道这个问题被问过几次,但是我遇到的答案越多,我就越困惑。
给定我有一个表Categories
并且在此表中的列: Category1
, Category2
, Category3
等。如何编写如下所示的方法并使用参数(在这种情况下为catno
)
尽我所能简化;
public List<string> GetProductCategories(int catno)
{
using (var ctx = new myEntities())
{
return (from c in ctx.Categories
select c.Category1).ToList();
//1 being the catno parameter obviously
}
}
我绝对不希望使用动态的LINQ库,因为它不是类型安全的。 尽管(显然)一个有效的答案会很好,但仍提供了对该问题和解决方案的详细说明。
提前致谢
public List<string> GetProductCategories(int catno)
{
string catName = string.Format("Category{0}", catno);
using (var ctx = new myEntities())
{
var result = ctx.Categories.Select(x => {
var prop = x.GetType().GetProperty(catName);
if (prop == null)
{
return double.NaN;
}
return double.Parse(prop.GetValue(x).ToString());
}).ToList();
return result.Where(x => !double.IsNaN(x)).ToList();
}
}
如果您想要完整的类型安全性,除了使用开关大小写将整数映射到其对应的类别,我看不到其他方法:
public List<string> GetProductCategories(int catno)
{
using (var ctx = new myEntities())
{
switch (catno)
{
case 1:
return ctx.Categories.Select(c => c.Category1).ToList();
case 2:
return ctx.Categories.Select(c => c.Category2).ToList();
default:
throw new ArgumentException("Category number not supported!");
}
}
}
您显然可以做的另一件事是重构代码,以便获得包含字符串属性以及数字的Category类的列表,然后可以编写如下代码:
return ctx.Categories.Where(c => c.CategoryNumber == catno)
.Select(c => c.CategoryDescription)
.ToList();
我认为您可能应该重构代码。 看到“ Category1”和“ Category2”时,我闻到不好的设计,听起来这些应该是“类别”列表中的项目。
也是关于Dynamic Linq的评论,例如,如果您收到来自无法控制的客户端的请求,则使用Dynamic linq并没有错。 如果找不到该属性,则可以简单地返回一个错误。
您可以定义基于字符串名称选择属性的表达式。 然后在IQueryable
接口中,可以在Select
参数中使用它。 但是,您将需要使用方法语法:
public List<string> GetProductCategories(int catno)
{
var parameter = Expression.Parameter(typeof(Category));
var property = Expression.Property(parameter, $"Category{catno}");
var selector = Expression.Lambda<Func<Category, string>>(property, parameter);
using (var ctx = new myEntities())
{
return ctx.Categories
.Select(selector)
.ToList();
}
}
Expression.Property
方法正在执行一些类型检查,因此,如果在Category
上没有定义给定的属性,它将抛出异常。 例如,如果没有Category0
属性,此操作将失败:
var property = Expression.Property(parameter, "Category0");
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.