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.