繁体   English   中英

实体框架-LINQ-动态列名

[英]Entity Framework - LINQ - Dynamic Column Names

我知道这个问题被问过几次,但是我遇到的答案越多,我就越困惑。

给定我有一个表Categories并且在此表中的列: Category1Category2Category3等。如何编写如下所示的方法并使用参数(在这种情况下为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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM