在ASP.NET Core中,即使使用了延迟加载,虚拟属性仍然无法加载。

3
首先,我阅读了所有与此问题相关的答案,但迄今为止没有任何帮助,所以请在标记为重复之前仔细阅读一次。
我创建了一个名为ProjectMaster的实体,它具有一个名为ClientMaster的虚拟属性。 它在我使用MVC时加载数据。 但现在我已经迁移到CORE,在这里它没有被加载。 经过谷歌搜索,我知道需要实现两件事才能使用延迟加载加载虚拟属性:
  • 安装Microsoft.EntityFrameworkCore.Proxies
  • 在startup中的ConfigureServices调用UseLazyLoadingProxies()服务
我已经完成了两个步骤以及各种替代方法。 但是我仍然无法加载数据。 这里我分享实体和配置服务方法。 实体 :
[Table("ProjectMaster")]
public partial class ProjectMaster
{
    [Key]
    public Guid ProjectId { get; set; }

    [Required]
    [StringLength(500)]
    public string ProjectName { get; set; }

    [Required]
    [StringLength(500)]
    public string ProjectCode { get; set; }

    public Guid ClientId { get; set; }

    public Guid CreatedBy { get; set; }

    public virtual ClientMaster ClientMaster { get; set; }
}

[Table("ClientMaster")]
public partial class ClientMaster
{
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
    public ClientMaster()
    {
        ProjectMasters = new HashSet<ProjectMaster>();
    }

    [Key]
    public Guid ClientId { get; set; }

    [Required]
    [StringLength(100)]
    public string ClientName { get; set; }

    public Guid CreatedBy { get; set; }

    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
    public virtual ICollection<ProjectMaster> ProjectMasters { get; set; }
}

初创企业:

   public void ConfigureServices(IServiceCollection services)
    {
        services.Configure<CookiePolicyOptions>(options =>
        {
            // This lambda determines whether user consent for non-essential cookies is needed for a given request.
            options.CheckConsentNeeded = context => true;
            options.MinimumSameSitePolicy = SameSiteMode.None;
        });

        services.AddEntityFrameworkProxies();
        services.AddDbContextPool<ApplicationDBContext>(options =>
        {
            options.UseSqlServer(Configuration.GetConnectionString("amcConn"));
            options.UseLazyLoadingProxies(true);
        });
        //services.AddDbContextPool<ApplicationDBContext>(options => options.UseSqlServer(Configuration.GetConnectionString("amcConn")));
       // services.AddDbContextPool<ApplicationDBContext>(options => options.UseLazyLoadingProxies().UseSqlServer(Configuration.GetConnectionString("amcConn")));


        services.AddSession();
        services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);

    }

控制器:

public ApiResult<List<ProjectMaster>> getallProject()
    {
        try
        {
            AMCContext _contect = new AMCContext();
            return new ApiResult<List<ProjectMaster>>
            (new ApiResultCode(ApiResultType.Success), _contect.ProjectMasters.ToList());
        }

这是我迄今为止所尝试的所有努力。

需要注意的一点是,此实体位于类库项目中,并已加载所有必要的包。

如果你有一些有用的建议,请告诉我。

2个回答

2
最初的回答:我目前使用的版本是:

我目前正在使用的版本

<PackageReference Include="Microsoft.EntityFrameworkCore.Proxies" Version="2.2.4" />

以下代码对我有用:

使用下面的代码对我起作用

services.AddDbContextPool<ApplicationDbContext>(options =>
 options.UseLazyLoadingProxies()
 .UseSqlServer(configuration.GetConnectionString("DefaultConnection"));

You can remove this line of code

services.AddEntityFrameworkProxies();

最初的回答

示例实体

public class Post : BaseEntity
{
    public string Title { get; set; }
    public string ShortDescription { get; set; }
    public string Content { get; set; }
    public PostStatus PostStatus { get; set; }
    public int Views { get; set; }
    public virtual User User { get; set; }
    public virtual ICollection<Comment> Comments { get; set; }
    public virtual Media Medias { get; set; }
}

public class Comment : BaseEntity
{
    public string Content { get; set; }
    public virtual Comment ParentComment { get; set; }
    public virtual Post Post { get; set; }
    public virtual User? User { get; set; }
    public CommentStatus CommentStatus { get; set; }
}

如果我的答案对你不起作用,你可以尝试像这样使用Include。最初的回答。
   var comments = await _unitOfWork.Repository<Comment>().Query()
                .Include(x => x.User)
                .Include(c => c.Post)
                .Select(x => new CommentViewModel
                {
                    User = _mapper.Map<User, UserViewModel>(x.User),
                    Post = _mapper.Map<Post, PostViewModel>(x.Post),
                    Comment = _mapper.Map<Comment, CommentDto>(x),
                })
                .ToListAsync();

它可以通过Include工作,但那会添加急切加载方法。我想通过延迟加载来实现这一点。而且我已经尝试了你建议的所有方法。 - Rajan Mishra
嗯,我可以建议的另一件事是删除 obj 和 debug 文件夹,然后进行清理。重新构建并再次运行您的项目。 - Tony Ngo
我已经尝试了你建议的方法,但也没有起作用。我无法弄清楚为什么这个简单的步骤对我没有结果。 - Rajan Mishra

2
当你使用懒加载时,它会在你尝试访问该对象时加载该值。您可以使用foreach循环来实现此目的,如下所示:

原始答案: "最初的回答"
 var foos = context.Foos.ToList();
 foreach (var Foo in foos )
 {
     var result = Foo.Id;  //This should load the value now
 }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接