user1140479
user1140479

Reputation:

EF6 lazy loading not working

I have these objects:

public class Domain : EntityTypeConfiguration<Domain>, IEntity
{
    [Key]
    public int Id { get; set; }

    [Required]
    public string Name { get; set; }

    public Guid Guid { get; set; }

    public ICollection<Website> Websites { get; set; }
}

public class Website: EntityTypeConfiguration<Website>, IEntity
{
    [Key]
    public int Id { get; set; }

    [Required]
    public string Name { get; set; }

    [Range(1, int.MaxValue)]
    public int DomainId { get; set; }

    public string Description { get; set; }

    [DatabaseGenerated(DatabaseGeneratedOption.Computed)]

    public DateTime CreationDate { get; set; }

    [Required]
    public Guid Guid { get; set; }

    [Required]
    public string LanguageIds { get; set; }

    public bool AllowToSharedTemplates { get; set; }

    public int PublishWebsiteId { get; set; }

    [Required]
    public string WebsiteUrl { get; set; }

    public virtual Domain Domain { get; set; }
}

When I want all the websites I want the connected Domains as well (each website has one domain). But somehow this does not work.

    public IList<T> GetAll()
    {
        IList<T> ret;

        using (IocDbContext db = Context.CreateContext())
        {
            DbSet<T> dbSet = db.Set<T>();
            ret = dbSet.ToList();
        }

        return ret;
    }

The CreateContext

    public IocDbContext CreateContext()
    {
        IocDbContext rety=  new IocDbContext(_siteType.ConnectionString);
        rety.Configuration.ProxyCreationEnabled = true;

        return rety;
    }

As you can see I have a generic repository. It works fine with just one object, but with navigation properties not. With lazy loading, it does not find the navigation property (domain in this case). I get this error:

The 'ObjectContent`1' type failed to serialize the response body for content type 'application/json; charset=utf-8'.

When I try to map the DTO to an object:

public static Objects.Website ToModel(this Data.Contexts.Website value)
    {
        if (value == null)
            return null;

        return new Website
        {
            Id = value.Id,
            Name = value.Name,
            Domain = value.Domain?.ToModel()
        };
    }

Upvotes: 0

Views: 188

Answers (1)

DavidG
DavidG

Reputation: 118947

Because you have your context wrapped in a using statement, lazy loading would never work because by the time you leave the GetAll() method, the context has been disposed and the connection to the database has been closed.

As much as lazy loading looks like a great option, I would highly recommend against using it unless you know what you're doing. It's much safer to explicitly load the data you need.

Upvotes: 1

Related Questions