Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Entity framework navigation property is null

I have 2 simple classes:

public class Setting
{
    [Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public Guid SettingId { get; set; }

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

    public String Value { get; set; }

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

public class SettingCategory
{
    [Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public Guid SettingCategoryId { get; set; }

    [Required]
    public String Value { get; set; }

    public ICollection<Setting> Settings { get; set; }
}

When I retrieve a SettingCategory from the database the collection Settings is always null.

When I make it a virtual then it will say: The ObjectContext instance has been disposed and can no longer be used for operations that require a connection.

How can I access my Settings list?

The other way around works, if I retrieve a Setting from the database the SettingCategory property is filled.

This is my initial code-migrations script:

CreateTable(
    "dbo.Settings",
    c => new
        {
            SettingId = c.Guid(nullable: false, identity: true),
            Name = c.String(nullable: false),
            Value = c.String(),
            SettingCategory_SettingCategoryId = c.Guid(nullable: false),
        })
    .PrimaryKey(t => t.SettingId)
    .ForeignKey("dbo.SettingCategories", t => t.SettingCategory_SettingCategoryId, cascadeDelete: true)
    .Index(t => t.SettingCategory_SettingCategoryId);

CreateTable(
    "dbo.SettingCategories",
    c => new
        {
            SettingCategoryId = c.Guid(nullable: false, identity: true),
            Value = c.String(nullable: false),
        })
    .PrimaryKey(t => t.SettingCategoryId);

And this is the part that gets it from the database:

public SettingCategory Get(Guid settingCategoryId)
{
    using (var context = new BackofficeContext())
    {
        return context
            .SettingCategories
            .FirstOrDefault(s => s.SettingCategoryId == settingCategoryId);
    }
}

Answer

I forgot the include in .SettingCategories, but I was trying it with a lambda:

public SettingCategory Get(Guid settingCategoryId)
{
    using (var context = new BackofficeContext())
    {
        return context
            .SettingCategories
            .Include(s => s.Settings)
            .FirstOrDefault(s => s.SettingCategoryId == settingCategoryId);
    }
}

That doesn't work, but this does:

public SettingCategory Get(Guid settingCategoryId)
{
    using (var context = new BackofficeContext())
    {
        return context
            .SettingCategories
            .Include("Settings")
            .FirstOrDefault(s => s.SettingCategoryId == settingCategoryId);
    }
}
like image 492
Roger Far Avatar asked Nov 02 '12 17:11

Roger Far


People also ask

What are navigation properties in Entity Framework?

A navigation property is an optional property on an entity type that allows for navigation from one end of an association to the other end. Unlike other properties, navigation properties do not carry data.

What is LazyLoadingEnabled entity framework?

LazyLoadingEnabled is specifically set to true to prevent the related entities from loading in the context I'm using. A drug class has a list of drugidentity objects in it. public class Drug { public virtual List<DrugIdentity> DrugIdentities { get; set; } }

What is ICollection in Entity Framework?

ICollection represents a type of collection. specifying a collection as an ICollection allows you to use any type of collection in your code that implements the ICollection interface.


1 Answers

Because you are disposing of your BackofficeContext you cannot use LazyLoading, which is what is happening when you make Settings virtual.

You can either increase the lifetime of your BackofficeContext, or eager load Settings. You can use eager loading with Include.

public SettingCategory Get(Guid settingCategoryId)
{
    using (var context = new BackofficeContext())
    {
        return context
            .SettingCategories
            .Include(s => s.Settings)
            .FirstOrDefault(s => s.SettingCategoryId == settingCategoryId);
    }
}
like image 109
cadrell0 Avatar answered Sep 25 '22 17:09

cadrell0