.net 实体框架核心2.0带多对多问题的选择查询
下面是模型.net 实体框架核心2.0带多对多问题的选择查询,.net,asp.net-core,entity-framework-core,.net,Asp.net Core,Entity Framework Core,下面是模型 class Product { public int Id { get; set; } public ICollection<Categorization> Categorization { get; set; } } class Categorization { public int ProductId { get; set; } public Product Product { get; set; } public int
class Product
{
public int Id { get; set; }
public ICollection<Categorization> Categorization { get; set; }
}
class Categorization
{
public int ProductId { get; set; }
public Product Product { get; set; }
public int CategoryId { get; set; }
public Category Category { get; set; }
}
class Category
{
public int Id { get; set; }
public ICollection<Categorization> Categorization { get; set; }
}
当我们调用Api时,我得到以下错误:
System.ArgumentNullException:值不能为null。参数名称:源
在System.Linq.Enumerable.选择[TSource,TResult](IEnumerable
1 source,Func
2选择器)
product.Categorization
为空,因为它未加载。如果您希望延迟加载来处理加载,则必须将product.Categorization
属性设置为虚拟属性(在本例中,还包括您希望在Categorization
类中延迟加载的属性,Category
)
编辑:在您的示例中,您应该使用Include
和然后Include
加载数据,因为您知道您需要数据:
_context.Products
.Include( p => p.Categorization )
.ThenInclude( c => c.Category )
.ToList()
product.Categorization
为空,因为它未加载。如果您希望延迟加载来处理加载,则必须将product.Categorization
属性设置为虚拟属性(在本例中,还包括您希望在Categorization
类中延迟加载的属性,Category
)
编辑:在您的示例中,您应该使用Include
和然后Include
加载数据,因为您知道您需要数据:
_context.Products
.Include( p => p.Categorization )
.ThenInclude( c => c.Category )
.ToList()
尝试将虚拟对象添加到以下对象:
class Product
{
public int Id { get; set; }
public virtual ICollection<Categorization> Categorization { get; set; }
}
class Categorization
{
public int ProductId { get; set; }
public virtual Product Product { get; set; }
public int CategoryId { get; set; }
public virtual Category Category { get; set; }
}
class Category
{
public int Id { get; set; }
public virtual ICollection<Categorization> Categorization { get; set; }
}
类产品
{
公共int Id{get;set;}
公共虚拟ICollection分类{get;set;}
}
类分类
{
public int ProductId{get;set;}
公共虚拟产品产品{get;set;}
public int CategoryId{get;set;}
公共虚拟类别{get;set;}
}
类别
{
公共int Id{get;set;}
公共虚拟ICollection分类{get;set;}
}
尝试向以下对象添加虚拟对象:
class Product
{
public int Id { get; set; }
public virtual ICollection<Categorization> Categorization { get; set; }
}
class Categorization
{
public int ProductId { get; set; }
public virtual Product Product { get; set; }
public int CategoryId { get; set; }
public virtual Category Category { get; set; }
}
class Category
{
public int Id { get; set; }
public virtual ICollection<Categorization> Categorization { get; set; }
}
类产品
{
公共int Id{get;set;}
公共虚拟ICollection分类{get;set;}
}
类分类
{
public int ProductId{get;set;}
公共虚拟产品产品{get;set;}
public int CategoryId{get;set;}
公共虚拟类别{get;set;}
}
类别
{
公共int Id{get;set;}
公共虚拟ICollection分类{get;set;}
}
发生错误的原因是product.Categorization
为空。实体框架核心2.1及以上版本支持延迟加载。请检查特定产品的分类是否不为空,并尝试执行即时加载(尽管根据文档,这可能不是必需的) 例如:
foreach (var product in _context.Products.Include(p => p.Categorization).ToList()){
if (product.Categorization != null) {
var categories = product.Categorization.Include(c => c.Category).Select(c => c.Category);
...
}
}
另外,请检查您是否已正确配置多对多关系,因为它要求您以以下方式定义复合主键:
override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Categorization>().HasKey(c => new { c.ProductId, c.CategoryId});
}
在模型创建时覆盖void(ModelBuilder ModelBuilder)
{
modelBuilder.Entity().HasKey(c=>new{c.ProductId,c.CategoryId});
}
请检查本教程,因为它可能很有用:发生错误是因为
product.Categorization
为空。实体框架核心2.1及以上版本支持延迟加载。请检查特定产品的分类是否不为空,并尝试执行即时加载(尽管根据文档,这可能不是必需的) 例如:
foreach (var product in _context.Products.Include(p => p.Categorization).ToList()){
if (product.Categorization != null) {
var categories = product.Categorization.Include(c => c.Category).Select(c => c.Category);
...
}
}
另外,请检查您是否已正确配置多对多关系,因为它要求您以以下方式定义复合主键:
override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Categorization>().HasKey(c => new { c.ProductId, c.CategoryId});
}
在模型创建时覆盖void(ModelBuilder ModelBuilder)
{
modelBuilder.Entity().HasKey(c=>new{c.ProductId,c.CategoryId});
}
请检查本教程,因为它可能很有用:要查询所有产品及其类别,您可以尝试
Include
和Include
,如下所示:
public async Task<IActionResult> GetAllArticleAsync()
{
var articles = await _context.Articles
.Include(a => a.ArticleTags)
.ThenInclude(at => at.Tag)
.Select(a => new
{
Id = a.Id,
ArticleName = a.ArticleName,
Tags = a.ArticleTags.Select(at => at.Tag).ToList()
})
.ToListAsync();
return Ok(articles);
}
有关完整的演示,请参阅查询所有产品及其类别,您可以尝试
包括
和然后包括
,如下所示:
public async Task<IActionResult> GetAllArticleAsync()
{
var articles = await _context.Articles
.Include(a => a.ArticleTags)
.ThenInclude(at => at.Tag)
.Select(a => new
{
Id = a.Id,
ArticleName = a.ArticleName,
Tags = a.ArticleTags.Select(at => at.Tag).ToList()
})
.ToListAsync();
return Ok(articles);
}
有关完整的演示,请参阅这是EFCore,因此仅将属性设置为虚拟是不够的,必须对其进行配置:
使用延迟加载的最简单方法是安装Microsoft.EntityFrameworkCore.Proxies包,并通过调用UseLazyLoadingProxies来启用它
。除此之外,它仅由EF Core 2.1HI Moho支持,谢谢!我试着这样做,但它给我下面的错误。services.AddDbContext(b=>b.UseLazyLoadingProxies(),opts=>opts.UseNpgsql(connectionString));无法将lambda表达式转换为类型“ServiceLifetime”,因为它不是委托type@nemesv谢谢,出于性能原因,我很久以前就停止使用延迟加载了。@LavanyaPant-不确定,但在您当前的示例中,您应该急切地加载您知道将要使用的数据,更新了答案以反映这是EFCore,因此仅将属性设置为虚拟是不够的,必须对其进行配置:使用延迟加载的最简单方法是安装Microsoft.EntityFrameworkCore.Proxies包,并通过调用UseLazyLoadingProxies来启用它。除此之外,它仅由EF Core 2.1HI Moho支持,谢谢!我试着这样做,但它给我下面的错误。services.AddDbContext(b=>b.UseLazyLoadingProxies(),opts=>opts.UseNpgsql(connectionString));无法将lambda表达式转换为类型“ServiceLifetime”,因为它不是委托type@nemesv谢谢,出于性能原因,我很久以前就停止使用延迟加载。@LavanyaPant-不确定,但在您当前的示例中,您应该立即加载您知道将要使用的数据,更新答案以反映Hi Rahy,我按你说的做了尝试,但还是犯了同样的错误。您使用的是哪个版本的EFCore?添加virtual
不足以在EFCore中获得延迟加载。嗨,Rahy,我按照您所说的做了尝试,但仍然得到相同的错误。您使用哪个版本的EFCore?添加virtual
不足以在EFCore中获得延迟加载。我认为您的问题可能是