gpt4 book ai didi

ef-core-2.1 - 尽管急切获取 "attempt was made to lazy-load navigation property on detached entity"

转载 作者:行者123 更新时间:2023-12-04 12:39:07 36 4
gpt4 key购买 nike

我正在使用启用了延迟加载的 Entity Framework Core 2.1.2,并且正在使用 AsNoTracking 执行查询。我正在使用 Include 引入我的导航属性(一个集合)。

如果我的所有实体的集合中至少有一个 child ,那么一切正常。

但是,如果我的任何实体没有 child ,那么我会收到一个错误:

System.InvalidOperationException: Error generated for warning 'Microsoft.EntityFrameworkCore.Infrastructure.DetachedLazyLoadingWarning: An attempt was made to lazy-load navigation property 'Children' on detached entity of type 'ParentProxy'. Lazy-loading is not supported for detached entities or entities that are loaded with 'AsNoTracking()'.'



这是问题的再现(在使用 NuGet 引入 Microsoft.EntityFrameworkCore 2.1.2、Microsoft.EntityFrameworkCore.Proxies 2.1.2、Microsoft.EntityFrameworkCore.InMemory 2.1.2 后,它可以从控制台应用程序运行):
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.EntityFrameworkCore;

namespace LazyLoadingIssue
{
public class Parent
{
public int Id { get; set; }
public string ParentName { get; set; }
public virtual ICollection<Child> Children { get; set; }
}

public class Child
{
public int Id { get; set; }
public int ParentId { get; set; }
public virtual Parent Parent { get; set; }
public string ChildName { get; set; }
}

public class Program
{
public static void Main(string[] args)
{
SetupDatabase(setupToFail: true);
PerformTest();

Console.WriteLine("Press any key to finish");
Console.ReadLine();
}

private static void PerformTest()
{
using (var db = new MyContext())
{
try
{
IQueryable<Parent> parents = db.Rounds.Include(r => r.Children).AsNoTracking();
foreach (Parent parent in parents)
{
Console.WriteLine($"Parent (Id={parent.Id}) '{parent.ParentName}'");
foreach (Child child in parent.Children)
{
Console.WriteLine($" - Child (Id={child.Id}, ParentId={child.ParentId}) '{child.ChildName}'");
}
}

Console.WriteLine("** WORKED **");
}
catch (Exception ex)
{
Console.WriteLine("** FAILED **");
Console.WriteLine(ex);
}
}
}

private static void SetupDatabase(bool setupToFail)
{
using (var db = new MyContext())
{
db.Database.EnsureDeleted();
db.Database.EnsureCreated();

var parent1 = new Parent
{
ParentName = "First sample parent (has children)",
Children = new List<Child>
{
new Child {ChildName = "child-1"},
new Child {ChildName = "child-2"},
new Child {ChildName = "child-3"}
}
};
var parent2 = new Parent
{
ParentName = $"Second sample parent ({(setupToFail ? "with no children" : "has children")})",
Children = new List<Child>()
};
if (!setupToFail)
parent2.Children.Add(new Child {ChildName = "child-4"});
db.AddRange(parent1, parent2);
db.SaveChanges();
}
}
}


public class MyContext : DbContext
{
public DbSet<Parent> Rounds { get; set; }

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder
// .UseSqlServer(@"Server=(localdb)\mssqllocaldb;Database=_ModelApp;Trusted_Connection=True;Connect Timeout=5;ConnectRetryCount=0")
.UseInMemoryDatabase(databaseName: "_modelApp")
.UseLazyLoadingProxies()
;
}
}

}

难道我做错了什么?或者这是 EF Core 中的错误? (我也发布了 an issue there。)

最佳答案

对于后代,这里是 response from the EF Core team :

This is because lazy-loading isn't supported for NoTracking queries (#10042) but we tried to not make it throw if it looked like lazy-loading wasn't needed. In retrospect it might have been better to always throw. Note that the warning can be configured to not throw using ConfigureWarnings in the DbContextOptionsBuilder.



以防万一它对某人有用,我最终做的是创建第二个“ReadOnlyRepository”,配置为不使用延迟加载并始终返回未跟踪的集合。我使用这个存储库进行查询,在这些查询中我永远不会保留对任何实体的更改,其中结果集可能很大并且何时需要良好执行。
public class ReadOnlyRepository : MainDbContextBase, IReadOnlyRepository
{
public ReadOnlyRepository(IConfigurationSettings configurationSettings)
: base(configurationSettings, false)
{
}

public IQueryable<T> Retrieve<T>() where T : class, IAmAnAggregateRoot
{
return GetDbSet<T>().AsNoTracking();
}
}

public class MainDbContextBase : DbContext
{
private readonly IConfigurationSettings configurationSettings;
private readonly bool useLazyLoading;

protected MainDbContextBase(IConfigurationSettings configurationSettings, bool useLazyLoading)
{
this.configurationSettings = configurationSettings;
this.useLazyLoading = useLazyLoading;
}

protected DbSet<T> GetDbSet<T>() where T : class
{
return Set<T>();
}

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
if (!optionsBuilder.IsConfigured)
{
optionsBuilder
.UseLazyLoadingProxies(useLazyLoading)
.UseSqlServer(configurationSettings.ConnectionString);
}
}

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
...
}
}

}

关于ef-core-2.1 - 尽管急切获取 "attempt was made to lazy-load navigation property on detached entity",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52107513/

36 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com