Virtual property not getting loaded after lazy loading too in ASP.NET Core

.net-core asp.net-core asp.net-core-mvc c# entity-framework-core

Question

First of all I read all the answers belonged to this problem but nothing helped so far so read it once before marking it duplicate.

I have created an entity named ProjectMaster which is having a virtual property named ClientMaster. It is loading data while i was working in mvc only. But now I have migrated to CORE and here it is not getting loaded. After googling i knew that there are two thing that to be implemented for loading the virtual properties using lazy loading.

  • Installing the Microsoft.EntityFrameworkCore.Proxies
  • Call the UseLazyLoadingProxies() service in ConfigureServices inside startup

I have done both of the step and also the various alternatives. But still I am unable to load the data. Here I am sharing both the entity and congfigurationservice method.

Entity :

[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; }
}

StartUp :

   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);

    }

Controller :

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

Here all the efforts I have tried so far.

One thing to be notice here that this entity is present inside a class library project and all the necessary packages has been loaded in it.

Give me some useful suggestions if you have.

1
3
12/2/2019 2:54:55 PM

Accepted Answer

The version I'm currently using

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

Using below code work for me

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

You can remove this line of code

services.AddEntityFrameworkProxies();

Sample entities

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; }
}

If my answer not work for you you can try something like this by using 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();
2
7/25/2019 2:36:18 PM

Popular Answer

When you use lazy loading, it loads the value when you try to access that object. You can use foreach loop for this purpose like shown below :

 var foos = context.Foos.ToList();
 foreach (var Foo in foos )
 {
     var result = Foo.Id;  //This should load the value now
 }


Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow