实体框架代码第一 - 关系

时间:2016-08-11 23:58:26

标签: c# entity-framework asp.net-web-api asp.net-web-api2

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

我的数据库种子代码是

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

所有内容都存储在数据库中,我认为我的课程声明存在问题,因为当我想获得Categories时,我无法看到CategoryTexts

这是在浏览器中输出

output in browser

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

这是我的Category和CategoryText实体

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

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

请帮助我了解更改代码的位置

1 个答案:

答案 0 :(得分:2)

您需要急切加载您的关系(在查询时使用Include),例如:

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

或者您可以显式加载它们(使用context.Entry(x).[Reference|Collection](x).Load(),例如:

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

或者您可以使用代理自动加载(延迟加载)...但为此,您的外国实体和集合必须在POCO中标记为virtual

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

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

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

还要记住,在访问属性时,上下文必须是“活着的”(未处理),以便有可以加载它们的实时上下文

相关文档的链接:https://msdn.microsoft.com/en-us/data/jj574232.aspx