简体   繁体   中英

Entity Framework Code First - Relationships

I am trying to add relationships to my entities using EF Code First in Web API project

My Database Seed code is

internal class ProductDbInitializer : DropCreateDatabaseAlways<ProductDbContext>
{
    protected override void Seed(ProductDbContext context)
    { 
        Category category = new Category();
        LanguagesDbContext languagesDbContext = new LanguagesDbContext();
        List<Language> languages = new List<Language>
        {
            new Language {Name="English",Code="en" },
            new Language {Name="Italian", Code="it" },
            new Language {Name="Russian",Code="rus" },
        };

        languagesDbContext.Languages.AddRange(languages);

        context.Categories.Add(category);

        List<CategoryText> categoryText = new List<CategoryText>();

        foreach (var language in languages)
        {
            string name = string.Empty;

            switch (language.Code)
            {
                case "en":
                    name = "paper";
                    break;
                case "it":
                    name = "carta";
                    break;
                case "rus":
                    name = "бумага";
                    break;
                default:
                    name = "paper";
                    break;
            }

            categoryText.Add(new CategoryText
            {
                Category = category,
                Language = language,
                Name = name
            });
        }

        category.CategoryTexts.Add(categoryText[1]);
        context.CategoryTexts.AddRange(categoryText);

        context.SaveChanges();
    }
}

everything is stored in DB and I think problem in declaration of my classes, because when I want to get Categories I have not able to see CategoryTexts

this is output in browser

在浏览器中输出

but in database I have my CategoryTexts added with valid CategoryId .

this is my Category and CategoryText Entities

public class Category
{
    public Category()
    {
        CategoryTexts = new List<CategoryText>();
    }

    public int Id { get; set; }
    public ICollection<Product> Products { get; set; }
    public ICollection<CategoryText> CategoryTexts { get; set; }
}

and

public class CategoryText
{
    public int Id { get; set; }
    public int CategoryId { get; set; }
    public int LanguageId { get; set; }

    [ForeignKey("CategoryId")]
    public Category Category { get; set; }

    [ForeignKey("LanguageId")]
    public Language Language { get; set; }
    public string Name { get; set; }
}

Please help me to understand where do I need to change code

You need to either eager load your relationships (using Include when you query), for example:

var myList = context.Products.Include("Categories").Include("CategoryTexts").ToList();

Or you can explicitly load them (with context.Entry(x).[Reference|Collection](x).Load() , for example:

var myProduct = context.Products.First();
context.Entry(myProduct).Collection(x => x.Categories).Load();

Or:

var myCategoryText = context.CategoryText.First();
context.Entry(myCategoryText).Reference(x => x.Language).Load();

Or you can have them auto-load (lazy loading) using proxies... but for that, your foreign entities and collections must be marked virtual in your POCOs:

public class Category
{
    public Category()
    {
        CategoryTexts = new List<CategoryText>();
    }

    public int Id { get; set; }
    public virtual ICollection<Product> Products { get; set; }
    public virtual ICollection<CategoryText> CategoryTexts { get; set; }
}

and

public class CategoryText
{
    public int Id { get; set; }
    public int CategoryId { get; set; }
    public int LanguageId { get; set; }

    [ForeignKey("CategoryId")]
    public virtual Category Category { get; set; }

    [ForeignKey("LanguageId")]
    public virtual Language Language { get; set; }
    public string Name { get; set; }
}

You also need to have proxy creation and lazy loading turned on, but that's the default in EF6.

Also remember that the context must be "alive" (not disposed) when accesing the properties so that there's a live context where they can be loaded

Link to related documentation: https://msdn.microsoft.com/en-us/data/jj574232.aspx

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM