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表示法作为普通的静态方法访问扩展方法。