实体框架代码第一

实体框架代码第一

本文介绍了实体框架代码第一 - 关系的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述



我的数据库种子代码是


$ b我正在尝试使用EF Code First在Web API项目中添加关系到我的实体$ b

 内部类ProductDbInitializer:DropCreateDatabaseAlways< ProductDbContext> 
{
protected override void Seed(ProductDbContext context)
{
类别category = new Category();
LanguagesDbContext languagesDbContext = new LanguagesDbContext();
列表<语言> languages = new List< Language>
{
new Language {Name =English,Code =en},
new Language {Name =Italian,Code =it},
new语言{Name =Russian,Code =rus},
};

languagesDbContext.Languages.AddRange(languages);

context.Categories.Add(category);

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

foreach(语言中的var语言)
{
string name = string.Empty;

switch(language.Code)
{
caseen:
name =paper;
break;
caseit:
name =carta;
break;
caserus:
name =бумага;
break;
default:
name =paper;
break;
}

categoryText.Add(new CategoryText
{
类别=类别,
语言=语言,
名称=名称
});
}

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

context.SaveChanges();
}
}

所有内容都存储在DB中,我认为声明中的问题我的课程,因为当我想要得到类别我无法看到 CategoryTexts



这是在浏览器中输出





但在数据库中我有我的 CategoryTexts 添加了有效的 CategoryId



这是我的类别和类别文本实体

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

public int Id {get;组; }
public ICollection< Product>产品{get;组; }
public ICollection< CategoryText> CategoryTexts {get;组;
}

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

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

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

请帮助我了解我需要在哪里更改代码

解决方案

您需要加快关系(在查询时使用 Include ,例如:

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

或者您可以显式加载它们(使用 context.Entry(x))。例如:

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

或者:

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

或者您可以使用代理自动加载(懒惰加载)...但是,您的外部实体和集合必须标记为 virtual POCO:

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

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

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

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

您还需要启用代理创建和延迟加载,但这是EF6中的默认值。



还要记住上下文在访问属性时必须是活着的(不处理),以便有一个实时上下文可以被加载



链接到相关文档:


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

这篇关于实体框架代码第一 - 关系的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-15 15:11