C# 正在加载引用另一个表中相关数据的数据列表
已解决 我试图找出如何在实体框架中从表中检索相关数据的集合,但还没有解决这个问题 这是两个表之间的多对多关系,如下图所示: 我的问题是,我想检索与作者相关的书籍,这是BOOK表的ICollection,但当我返回时,它会给我一个空列表。 我已尝试使用显式加载解决此问题:C# 正在加载引用另一个表中相关数据的数据列表,c#,asp.net-mvc,entity-framework,C#,Asp.net Mvc,Entity Framework,已解决 我试图找出如何在实体框架中从表中检索相关数据的集合,但还没有解决这个问题 这是两个表之间的多对多关系,如下图所示: 我的问题是,我想检索与作者相关的书籍,这是BOOK表的ICollection,但当我返回时,它会给我一个空列表。 我已尝试使用显式加载解决此问题: public AUTHOR Read(int Aid) { using(var db = new LibraryDBEntities1()) { var author = db.AUTHORs
public AUTHOR Read(int Aid)
{
using(var db = new LibraryDBEntities1())
{
var author = db.AUTHORs.Find(Aid);
db.Entry(author).Collection(a => a.BOOKs).Load();
return author;
}
}
我也尝试过使用渴望加载来解决它
return db.AUTHORs.Where(a => a.Aid == Aid).Include("BOOKs").FirstOrDefault();
但它也不起作用。我试图按照microsoft文档的说明进行操作,但我一直无法找出我做错了什么。
谁能帮我解决这个问题,也许能解释一下我哪里做错了
编辑1
这就是OnModelCreating的外观。我应该在这里更改/添加代码吗?我一直在使用数据库优先的方法
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
throw new UnintentionalCodeFirstException();
}
编辑2
数据库连接应如下所示:
编辑3
我忘了提到我正在使用一个三层架构,包括一个表示层(MVC)、一个业务逻辑层和一个数据访问层。还有一个包含数据库的数据层,如下图所示
解决方案
所以我终于解决了!所以问题并不是我第一次想到的问题,而是我如何使用我的地图绘制工具。
我必须在我的模型中添加以下代码才能使其正常工作:
authorObj.BooksList = Mapper.Map<List<BOOK>, List<Book>>(aauthor.BOOKs.ToList());
authorbj.BooksList=Mapper.Map(aauther.BOOKs.ToList());
现在它可以正常工作了 由于是数据库优先的方法,请尝试将下面的映射添加到您的
OnModelCreating
函数中
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<BOOKs>()
.HasMany<AUTHORs>(b => b.AUTHORs)
.WithMany(a => a.BOOKs)
.Map(m => m.ToTable("BOOK_AUTHOR")
.MapLeftKey("ISBN")
.MapRightKey("Aid"));
// or like below
/* modelBuilder.Entity<BOOKs>()
.HasMany<AUTHORs>(s => s.AUTHORs)
.WithMany(c => c.BOOKs)
.Map(cs =>
{
cs.MapLeftKey("ISBN");
cs.MapRightKey("Aid");
cs.ToTable("BOOK_AUTHOR"); // Use the correct junction table name here. and correct key names
});*/
}
或
或者简单地说,在FirstOrDefault中直接使用谓词,而不使用WHERE子句
db.AUTHORs.Include(a => a.BOOKs).FirstOrDefault(a => a.Aid == Aid); // Same as above two queries.
更新:
var query = db.AUTHORs.Include(a => a.BOOKs).Where(a => a.Aid == Aid);
var firstBook = query.FirstOrDefault(); // Have a break point here. Please see what is in query via quick watch.
在QuickWatchforQuery(不是firstBook)中,您应该看到如下所示的Sql:
请在SSMS中直接执行SQL语句并在此处发布您的观察结果,如
- 您是否在查询中看到图书的联接
- 结果集是否包含书本中的列
OnModelCreating
函数中
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<BOOKs>()
.HasMany<AUTHORs>(b => b.AUTHORs)
.WithMany(a => a.BOOKs)
.Map(m => m.ToTable("BOOK_AUTHOR")
.MapLeftKey("ISBN")
.MapRightKey("Aid"));
// or like below
/* modelBuilder.Entity<BOOKs>()
.HasMany<AUTHORs>(s => s.AUTHORs)
.WithMany(c => c.BOOKs)
.Map(cs =>
{
cs.MapLeftKey("ISBN");
cs.MapRightKey("Aid");
cs.ToTable("BOOK_AUTHOR"); // Use the correct junction table name here. and correct key names
});*/
}
或
或者简单地说,在FirstOrDefault中直接使用谓词,而不使用WHERE子句
db.AUTHORs.Include(a => a.BOOKs).FirstOrDefault(a => a.Aid == Aid); // Same as above two queries.
更新:
var query = db.AUTHORs.Include(a => a.BOOKs).Where(a => a.Aid == Aid);
var firstBook = query.FirstOrDefault(); // Have a break point here. Please see what is in query via quick watch.
在QuickWatchforQuery(不是firstBook)中,您应该看到如下所示的Sql:
请在SSMS中直接执行SQL语句并在此处发布您的观察结果,如
- 您是否在查询中看到图书的联接
- 结果集是否包含书本中的列
OnMOdalCreating
,如下所示
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
}
return db.AUTHORs.Where(a => a.Aid == Aid).Include(a => a.BOOKs).FirstOrDefault();
[Table("BOOK_AUTHOR")]
public class BookAuthor
{
public int ISBN { get; set; }
public int AId { get; set; }
public virtual Book Book { get; set; }
public virtual Author Author { get; set; }
}
然后你可以像下面那样使用它
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
}
return db.AUTHORs.Where(a => a.Aid == Aid).Include(a => a.BOOKs).FirstOrDefault();
[Table("BOOK_AUTHOR")]
public class BookAuthor
{
public int ISBN { get; set; }
public int AId { get; set; }
public virtual Book Book { get; set; }
public virtual Author Author { get; set; }
}
附言:我强烈建议您为连接类型创建一个模型类
编辑
使用数据库优先的方法,基本上必须为数据库中的每个表创建一个模型类
因此,不要更改您的OnMOdalCreating
方法。添加一个新类,如下所示
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
}
return db.AUTHORs.Where(a => a.Aid == Aid).Include(a => a.BOOKs).FirstOrDefault();
[Table("BOOK_AUTHOR")]
public class BookAuthor
{
public int ISBN { get; set; }
public int AId { get; set; }
public virtual Book Book { get; set; }
public virtual Author Author { get; set; }
}
然后,您需要通过属性或fluentapi将属性绑定到主键属性。在那之后,你将能够找到一位拥有如下书籍的作者
var authorWithBooks = context.Authors
.Include(a => a.BookAuthors.Select(ba => ba.Book))
.Where(...)
.ToList();
EF 6包括多对多关系的默认约定。您需要在两端包含集合导航属性。因此,您的模型类定义非常好。您应该做的是更新
OnMOdalCreating
,如下所示
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
}
return db.AUTHORs.Where(a => a.Aid == Aid).Include(a => a.BOOKs).FirstOrDefault();
[Table("BOOK_AUTHOR")]
public class BookAuthor
{
public int ISBN { get; set; }
public int AId { get; set; }
public virtual Book Book { get; set; }
public virtual Author Author { get; set; }
}
然后你可以像下面那样使用它
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
}
return db.AUTHORs.Where(a => a.Aid == Aid).Include(a => a.BOOKs).FirstOrDefault();
[Table("BOOK_AUTHOR")]
public class BookAuthor
{
public int ISBN { get; set; }
public int AId { get; set; }
public virtual Book Book { get; set; }
public virtual Author Author { get; set; }
}
附言:我强烈建议您为连接类型创建一个模型类
编辑
使用数据库优先的方法,基本上必须为数据库中的每个表创建一个模型类
因此,不要更改您的OnMOdalCreating
方法。添加一个新类,如下所示
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
}
return db.AUTHORs.Where(a => a.Aid == Aid).Include(a => a.BOOKs).FirstOrDefault();
[Table("BOOK_AUTHOR")]
public class BookAuthor
{
public int ISBN { get; set; }
public int AId { get; set; }
public virtual Book Book { get; set; }
public virtual Author Author { get; set; }
}
然后,您需要通过属性或fluentapi将属性绑定到主键属性。在那之后,你将能够找到一位拥有如下书籍的作者
var authorWithBooks = context.Authors
.Include(a => a.BookAuthors.Select(ba => ba.Book))
.Where(...)
.ToList();
你是如何在你的c#模型中定义多对多关系的(你能从你的上下文文件的OnModelCreating@sam谢谢你的评论!我是实体框架新手,所以我不知道我应该更改上下文文件中的任何内容。我已经编辑了这个问题,并在OnModelCreatingwhat EF version you using?@ilkerkaran我使用的是EF version 6.4。0@JulijusE你不应该做任何事。我认为你的
。Include(“book”)
有问题。你能试试Include(a=>a.BOOKs)
吗?你是如何在你的c模型中定义很多关系的(你能从你的上下文文件的OnModelCreating@sam谢谢你的评论!我是实体框架新手,所以我不知道我应该更改上下文文件中的任何内容。我已经编辑了这个问题,并在OnModelCreatingwhat EF version you using?@ilkerkaran我使用的是EF version 6.4。0@JulijusE你不应该做任何事。我认为你的有问题。包括(“书籍”)
你能试试包括(a=>a.BOOKs)吗
?谢谢你的回答!我试过了,但没有成功。你认为我应该先迁移到代码而不是数据库,然后为连接表创建一个模型类,还是可以立即使用我正在采取的方法添加它?先迁移到代码取决于项目的需要。但我也会为连接添加一个模型这样,我的工作就更灵活了opinion@ilkerkaran据我所知,如果连接表