我知道这个问题被问过几次,但是我遇到的答案越多,我就越困惑。
鉴于我有一个表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
}
}
我绝对不要要使用Dynamic Linq库,因为它的类型不安全。尽管(显然)一个有效的答案会很好,但是提供了对该问题和解决方案的详细说明。
预先感谢
答案 0 :(得分:0)
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();
}
}
答案 1 :(得分:0)
如果您想要完全的类型安全性,除了使用开关大小写将整数映射到其对应的类别外,我没有其他方法:
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并没有错。如果找不到该属性,则可以简单地返回一个错误。
答案 2 :(得分:0)
您可以定义基于字符串名称选择属性的表达式。然后,在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");