当将实体模型转换为DTO时,我对Entity Framework Core(v2.0.1)有一个问题。基本上,通过该短语的任何其他版本,当我不想加载时,它是延迟加载的。这是一个简单的。NET Core Console应用程序(带有Microsoft. EntityFrameworkCore. SqlServer(2.0.1)包)。
using Microsoft.EntityFrameworkCore;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
namespace EfCoreIssue
{
class Program
{
static void Main(string[] args)
{
var dbOptions = new DbContextOptionsBuilder<ReportDbContext>()
.UseSqlServer("Server=.;Database=EfCoreIssue;Trusted_Connection=True;")
.Options;
// Create and seed database if it doesn't already exist.
using (var dbContext = new ReportDbContext(dbOptions))
{
if (dbContext.Database.EnsureCreated())
{
string alphas = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
foreach (char alpha in alphas)
{
var report = new Report { Title = $"Report { alpha }" };
for (int tagId = 0; tagId < 10; tagId++)
report.Tags.Add(new ReportTag { TagId = tagId });
dbContext.Reports.Add(report);
dbContext.SaveChanges();
}
}
}
using (var dbContext = new ReportDbContext(dbOptions))
{
var reports = dbContext.Reports
.Select(r => new ReportDto
{
Id = r.Id,
Title = r.Title,
Tags = r.Tags.Select(rt => rt.TagId)
})
.ToList();
}
}
}
class ReportDbContext : DbContext
{
public DbSet<Report> Reports { get; set; }
public ReportDbContext(DbContextOptions<ReportDbContext> options)
: base(options) { }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<ReportTag>().HasKey(rt => new { rt.ReportId, rt.TagId });
}
}
[Table("Report")]
class Report
{
[Key]
public int Id { get; set; }
public string Title { get; set; }
public virtual ICollection<ReportTag> Tags { get; set; }
public Report()
{
Tags = new HashSet<ReportTag>();
}
}
[Table("ReportTag")]
class ReportTag
{
public int ReportId { get; set; }
public int TagId { get; set; }
}
class ReportDto
{
public int Id { get; set; }
public string Title { get; set; }
public IEnumerable<int> Tags { get; set; }
}
}
现在,当执行ToList()
方法来检索数据时,它正在执行以下SQL
SELECT [r].[Id], [r].[Title]
FROM [Report] AS [r]
如您所见,它没有努力加入[ReportTag]
表,如果您实际尝试读取ReportDto
上的Tags
属性的值,那么它会触发另一个SQL查询
SELECT [rt].[TagId]
FROM [ReportTag] AS [rt]
WHERE @_outer_Id = [rt].[ReportId]
现在我知道EF Core不支持延迟加载,但在我看来这很像延迟加载。在这种情况下,我不希望它延迟加载。我试着改变var reports=dbContext。报告至var Reports=dbContext。报告。包括(r=
我甚至试着改变标签=r.Tags。选择(rt=
最后,在绝望中,我尝试更改var reports=dbContext。报告至var Reports=dbContext。报告。包括(r=
有没有人知道我可以做什么,这样它就可以加载到ReportDto了。标签属性?
正如您所注意到的,当前包含集合投影的EF核心投影查询存在两个问题—(1)它们导致每个集合执行N个查询;(2)它们执行缓慢。
问题(2)很奇怪,因为具有讽刺意味的是EF Core不支持延迟加载相关的实体数据,而这种行为有效地将其用于投影。至少可以通过使用ToList()或类似工具强制立即执行。
问题(1)目前无法解决。它通过查询进行跟踪:优化投影相关集合的查询,使其不会产生N 1数据库查询#9282,并根据路线图(减少N 1查询项)最终将在下一个EF Core 2.1版本中修复(改进)。
我能想到的唯一解决方法是(以更高的数据传输和内存使用为代价)使用即时加载,然后进行投影(在LINQ到实体的上下文中):
var reports = dbContext.Reports
.Include(r => r.Tags) // <-- eager load
.AsEnumerable() // <-- force the execution of the LINQ to Entities query
.Select(r => new ReportDto
{
Id = r.Id,
Title = r.Title,
Tags = r.Tags.Select(rt => rt.TagId)
})
.ToList();
我已经将读上下文和写上下文分开了,现在我将在默认情况下在ReadOnlyContext中启用LazyLoading。我也使用了下面的方法,但不幸的是它不起作用。 我的模型: 我的ef版本: EntityFramework核心版本2.1.2 我得到了这个错误: “为警告‘Microsoft.EntityFrameworkCore.Infrastructure.DetachedLazyLoadingW
考虑以下(非常简化的)实体: 在我的映射器中,我可以设置用户罚款,但是一旦执行以下代码(在数据库中保留任何更改之前)
我从这个网站上读到了关于懒惰加载的内容。启用或禁用LazyLoding “如果我们请求已启用LazyLoading的学生列表,数据提供程序将从数据库中获取所有学生,但每个StudentAddress属性在显式访问该属性之前不会加载。” 此语句表示,当我将设置为true时,将不会加载相关数据。然而 如果我设置延迟加载启用=true,上面的代码返回所有特技与他们的老师和地址。我在这里错过了什么?有人能
我正在使用启用延迟加载的实体框架5。我有以下代码: 但这有意义吗?我想确保公共属性订阅从不为null。由于虚拟实体框架覆盖了getter和setter以提供延迟加载功能。 我需要这个字段还是我可以只使用一个自动属性,如果没有订阅,我得到一个空列表?
当我从主viewController重定向到另一个viewController时,我得到了这个。 错误: Lazy 加载 NSBundle MobileCoreServices.framework, 已加载MobileCoreServices.framework, system group . com . apple . configuration profiles的系统组容器路径为/Users/
我在亲子关系中有几个实体:家庭(父母)和更新(孩子)。我想阅读没有相应更新的家庭列表。只有17个家庭,但大约有60,000个更新,所以我真的不想要更新。 我使用EntiesToDTO从Family实体生成DTO,并创建一个汇编器来将Family实体转换为FamilyDTO。汇编器的ToDTO方法如下所示: 当我运行汇编程序时,我发现每个生成的FamilyDTO都填充了Updates\u ID列表,