如何编写LINQ查询,选择一个属性,该属性是一个嵌套实体属性集合的字符串连接
本文关键字:属性 一个 集合 实体 字符串 连接 嵌套 查询 LINQ 何编写 选择 | 更新日期: 2023-09-27 18:11:41
试图提高我的查询效率,但不确定如何将这一切写为一个查询。我有一个域模型:
public class UserReport : Entity
{
public string Name { get; set; }
public List<string> Statuses { get; set; }
public List<GroupModel> Groups { get; set; }
public string Email { get; set; }
public string OfficeStates {get; set;} //Comma delimited list
}
public class GroupModel : Entity
{
public string Name {get; set;}
public string Type {get; set;
}
这是一个"复合实体",如果你愿意。表示这些集合的标准实体是具有User
对象的M2M关系实体:
public class User : Entity
{
public string FirstName { get; set; }
public string LastName { get; set; }
public ICollection<Status> Statuses { get; set; }
public ICollection<Group> Groups { get; set; }
public ICollection<Office> Offices { get; set; }
}
public class Office : Entity
{
//other properties
public State State { get; set; }
}
public class State : Entity
{
public string Name { get; set; }
public string Abbreviation { get; set; }
}
到目前为止,我得到了:
Context.DbSet<User>.Select(user => new UserReport()
{
Name = user.FirstName + ", " + user.LastName,
Email = user.Email,
Statuses = user.Statuses.Select(status => status.Name).ToList(),
Groups = user.Groups.Select(group => new GroupModel(){ Name = group.Name, Type = group.Type.Name}).ToList(),
OfficeStates = string.Join(",", user.Offices.Select(office => office.State.Abbreviation).ToList())
}).ToList();
抛出错误:
LINQ to Entities不能识别方法System。字符串连接(系统。字符串,System.Collections.Generic.IEnumerable ' 1[System.String])'方法,此方法不能转换为存储表达式。
我完全明白这是说什么,我知道如果我调用。tolist()之前我的选择它会起作用,但我需要有这是一个查询,所以我仍然可以有一个IQueryable应用过滤以后。当然,LINQ中一定有一些方法可以做到这一点。它可以在SQL中完成:将许多行连接到单个文本字符串中?如何通过LINQ实现?
您可以看到,即使在纯SQL中,这也不是微不足道的(for xml
,声明变量等)。据我所知,没有办法用纯LINQ做你想做的事情。但是,至少在某些情况下,您可以使用一个查询来完成此操作,尽管此查询与您在纯SQL中执行此操作的方式不同。在你的例子中,应该是这样的:
Context.DbSet<User>.Select(user => new // note, anonymous type here
{
Name = user.FirstName + ", " + user.LastName,
Email = user.Email,
Statuses = user.Statuses.Select(status => status.Name), // no ToList - this won't work
Groups = user.Groups.Select(group => new GroupModel(){ Name = group.Name, Type = group.Type.Name}), // no ToList()
OfficeStates = user.Offices.Select(office => office.State.Abbreviation) // no ToList(), no String.Join()
}).ToList() // here we materizized, and now we can concatenate strings by hand
.Select(c => new UserReport {
Name = c.Name,
Email = c.Email,
Statuses = c.Statuses.ToList(),
Groups = c.Groups.ToList(),
OfficeStates = String.Join(",", c.Offices)
});
在我测试的简单的情况下,这会生成一个数据库查询,并且该查询只接收您需要的列(尽管正如我所说,生成的查询在概念上与您在SQL中使用的查询不同)。因此,我建议尝试这种方法,看看会生成什么查询(请注意我在上面代码中的注释)。