Linq 实体框架-仅从列表中获取动态指定的特定列

Linq 实体框架-仅从列表中获取动态指定的特定列,linq,entity-framework,linq-to-sql,entity-framework-6,linq-expressions,Linq,Entity Framework,Linq To Sql,Entity Framework 6,Linq Expressions,我希望有一些灵活性,并提供一些接口来指定应该包含在最终选择中的列的列表 例如,对于这个表 public class Person { [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity), Key()] public int Id { get; set; } [Required] public string FirstName { get; se

我希望有一些灵活性,并提供一些接口来指定应该包含在最终选择中的列的列表

例如,对于这个表

    public class Person
    {
        [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity), Key()]
        public int Id { get; set; }

        [Required]
        public string FirstName { get; set; }

        [Required]
        public string LastName { get; set; }

        public string Address { get; set; }

        ...
    }
我想要一个案子

persons.Select(p => new { FirstName = p.FirstName, LastName = p.LastName }).ToList();
但另一次我想

persons.Select(p => new { FirstName = p.FirstName, LastName = p.LastName, Address = p.Address }).ToList();
在第三种情况下,我还需要其他东西。。。因此,我认为最好有一些灵活的机制,允许指定要提取的列的列表

你知道我该怎么做吗


我读了一些关于LINQ表达式的文章,我觉得这是一种正确的方法,但还不了解如何实现它…

如果您包括NuGet package System.LINQ.Dynamic,它非常简单:

var columns = new [] { "FirstName", "LastName" };
var selectText = "new (" + string.Join(", ", columns) + ")";
var result = Users.AsQueryable().Select(selectText);
还是为了类型安全

var columns = new Expression<Func<User, object>> [] { x => x.FirstName, x => x.Surname };
var selectText = "new (" + string.Join(", ", columns.Select(x => ((MemberExpression)x.Body).Member.Name)) + ")";
var result = Users.AsQueryable().Select(selectText);
var columns=newexpression[]{x=>x.FirstName,x=>x.lasname};
var selectText=“新建(“+string.Join(,”,columns.Select(x=>((MemberExpression)x.Body.Member.Name))+”;
var result=Users.AsQueryable().Select(selectText);
这是将表达式转换为字符串的库,该库将返回表达式,因此这不是最优化的方法,但与数据库查询相比,成本可能微不足道


您可以通过构建表达式来实现这一点,但库会为您完成所有工作。

基本上,这是正确的方式。通过使用类作为数据的“模型”,您只能让它更舒适和更安全。基本上,创建另一个Person类,其中包含表中的所有字段,或者仅包含该“Person”中所需的字段。这样做,而不仅仅是创建无名对象并将它们写入列表,这给了您更大的灵活性,因为您可以添加其他方法来转换此类中的数据

您还可以根据要初始化的字段向该类添加不同的构造函数。像这样:

var modelPersons = persons.Select(p => new ModelPerson(p.FirstName, p.LastName)).ToList();
如果您为需要的每个初始化都编写了一个构造函数,那么在查询时就会有可重用的短代码。当然,您仍然可以使用如下对象初始值设定项:

var modelPersons = persons.Select(p => new ModelPerson {
  FirstName = p.FirstName
  LastName = p.LastName
}).ToList();

它和你发布的一样长,但是最好使用一个对象,你可以定义自己,添加方法,格式化数据等。但是所有这些都是正确的方法。

来扩展Mant101的答案。您可以通过使用解决重复命名空间问题。另请参见SO问题。

您试过这两种表达方式吗?这就是解决问题的方法it@DFord,这两个表达式有什么问题吗?嗨,Mant101,谢谢你把我指给System.Linq.Dynamic。。。我试图将其添加到我的解决方案中,但不幸的是,我已经使用EntityFramework.Extended,而这一个在同一System.Linq.Dynamic命名空间中也有Select扩展,因此它们相互冲突。我尝试了EntityFramework.Extended中的方法,但它引发了异常。。。将继续朝那个方向挖掘。再次感谢…如果您有冲突,您可以使用普通的class name.methodname表示法作为普通的静态方法访问扩展方法。