【问题标题】:Entity Framework select many-to-many with concat text实体框架选择多对多与连接文本
【发布时间】:2018-08-26 01:11:19
【问题描述】:

图书:ID、名称、内容、出版
作者:身份证,姓名
是多对多的

Id   |   Name   |   Content   |   Publishment
1        book1    somecontent     some pub
2        book2     somecont        somepub

作者

Id   |   Name
1        Author1
2        Author2
3        Author3
4        Author4

图书作者

IdBook   |   IdAuthor
1            2
1            3
1            4
2            1
2            3

我怎样才能得到类似的东西:

Name   |   Content   |   Author
Book1    some content     Author2,Author3,Author3
Book2     somecontent      Author1,Author3

【问题讨论】:

  • 到目前为止你尝试了什么?

标签: c# entity-framework console-application


【解决方案1】:

有几种方法可以做到这一点。

我假设您使用的是 DB-first。如果是这种情况,您的实体将被创建为部分类。为您的 Book 类创建一个新的部分类文件,并添加一个新属性来检索作者姓名。像这样的:

public partial class Book
{
   public string AuthorNames => string.Join(", ", authors.Select(a => a.Name));
}

为防止多次访问数据库以检索相关作者,请在检索您的图书时使用 include。

var books = myContext.Books.Include(nameof(Book.authors));

另一种方法是使用投影来创建匿名类型。

var books = myContext.Books
   .Select(b => new { 
      b.Name, 
      b.Content, 
      AuthorNames = b.authors.Select(a => a.Name) 
   })
   .AsEnumerable()
   .Select(b => new {
      b.Name,
      b.Content,
      Authors = string.Join(", ", b.AuthorNames)
   });

【讨论】:

  • 感谢您的回答。但我有一个问题:无效的匿名类型成员声明符。必须使用成员分配、简单名称或成员访问来声明匿名类型成员。如果我使用 authors = string.Join(", ", b.authors.Select(a => a.Name)) 我有消息: LINQ to Entities 表达式无法识别方法“System.String Join(System.String , System.Collections.Generic.IEnumerable`1[System.String])”所以不能转换为存储表达式。 '我能做什么?
  • 啊,那是因为 Linq 无法将 string.Join() 转换为 SQL 以针对数据库执行。在使用该表达式之前,您必须将数据库查询到内存中(您可以通过调用 ToList() 来做到这一点)。我试图纠正答案。
  • 抱歉一连串的更正,这已经是漫长的一天了。
  • 第二个查询中的Include 是多余的:投影消除了它。一种可能的优化是使用AsEnumerable() 而不是ToList()
  • 是的,很重要。我什至不知道 AsEnumerable() 作为这个选项。编辑以纳入您的建议。谢谢!
猜你喜欢
  • 2021-05-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-01-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多