使用 Entity Framework 中的导航属性填充多对多关系 table
populate many-to-many relationship table using navigation properties in Entity Framework
我正在 asp.net mvc 应用程序中学习 Entity Framework。我有 3 个模型 -
AppModel、CategoryModel 和 App_CategoryModel(指定 AppModel 和 CategoryModel 之间的多对多关系)。其中的一个片段是:
public class CategoryModel
{
[Key]
public int id { get; set; }
public string Name {get; set; }
public virtual ICollection<App_CategoryModel> mapping { get; set; }
}
public class AppModel
{
[Key]
public int id { get; set; }
public string Name { get; set; }
public virtual ICollection<App_CategoryModel> mapping { get; set; }
}
public class App_CategoryModel
{
[Key]
public int id {get; set;}
public int AppId {get; set; }
public int CategoryId {get; set; }
public virtual AppModel App {get; set;}
public virtual CategoryModel Category {get; set;}
}
我遵循 'Code-first' 方法并且 table 已成功创建。但是,现在我被困在如何填充和显示这些信息上。
我有以下作为输入数据:
List<AppModel>
List<CategoryModel>
和 Dictionary<"appname", List<CategoryModel>>
我如何从这里继续,以便我可以更新映射 table?
另外,想了解这是否是表示数据的正确方法。由于一个应用程序可以有多个类别 - 我希望输出是唯一应用程序的集合以及每个应用程序的类别列表,例如:
Dictionary<AppModel, List<CategoryModel>>
编辑:
这是我根据 smoksnes-
的建议尝试的
List<CategoryModel> cat_list = new List<CategoryModel>();
CategoryModel c1 = new CategoryModel();
c1.Name = "string1";
cat_list.Add(c1);
CategoryModel c2 = new CategoryModel();
c2.Name = "string2";
cat_list.Add(c2);
List<AppModel> app_list = new List<AppModel>();
AppModel a1 = new AppModel();
a1.Name = "app1";
app_list.Add(a1);
AppModel a2 = new AppModel();
a2.Name = "app2";
app_list.Add(a2);
a1.mapping.Add(c1);
a1.mapping.Add(c2);
a2.mapping.Add(c1);
a2.mapping.Add(c2);
db.categories.AddRange(cat_list);
db.apps.AddRange(app_list);
db.SaveChanges();
此后,EF 正常工作 - 2 个类别、2 个应用程序和 4 个映射条目 table。
虽然这有效,但不确定是谁阻止 EF 为类别创建 4 个条目?
正如您在评论中提到的 Barry O´Kane 一样,没有理由保留 App_CategoryModel
模型。 EF 将为您管理。只有当它包含有关两个表之间关系的任何额外信息时,才应保留它。但根据你的例子,没有理由保留它。
public class CategoryModel
{
public CategoryModel()
{
AppModels = new List<AppModel>();
}
[Key]
public int id { get; set; }
public string Name {get; set; }
public virtual ICollection<AppModel> AppModels { get; set; }
}
public class AppModel
{
public AppModel()
{
// Not sure if this is actually needed anymore. But EF usually adds it.
CategoryModels = new List<CategoryModel>();
}
[Key]
public int id { get; set; }
public string Name { get; set; }
public virtual ICollection<CategoryModel> CategoryModels { get; set; }
}
关于你关于代表的问题,我认为没有必要。由于 AppModel
已经在其模型上连接了 CategoryModel
,因此没有理由 Dictionary
。您可以将其存储在 List<AppModel>
中。
IList<AppModel> myApps = context.AppModels.ToList();
foreach (var myApp in myApps)
{
Console.Writeline("App {0} has the following categories:", myApp.id);
foreach (var category in myApp.CategoryModels)
{
Console.Writeline(category.Name);
}
}
当您想向应用添加类别时:
// I don't know how you create your Context, so below it's just called context.
var newCategoryModel = new CategoryModel
{
Name = "SO is awesome!"
};
var appModel = context.AppModels.FirstOrDefault(x => x.id == 1);
appModel.CategoryModels.Add(newCategoryModel); // EF will automatically set foreign keys for you...
context.SaveChanges();
如果你想确保没有类别被添加两次:
public void AddCategory(int appId, string categoryName)
{
using(var context = new DbContext())
{
var category = context.CategoryModels.FirstOrDefault(x => x.Name == categoryName);
if(category == null)
{
// Only create new CategoryModel if it doesn't exist.
category = new CategoryModel
{
Name = categoryName
};
}
var appModel = new AppModel
{
id = appId
};
// Attach to save on db-trip
context.AppModels.Attach(appModel);
//TODO: Possibly check if this particular appModel already has this category?
appModel.CategoryModels.Add(category);
context.SaveChanges();
}
}
我正在 asp.net mvc 应用程序中学习 Entity Framework。我有 3 个模型 -
AppModel、CategoryModel 和 App_CategoryModel(指定 AppModel 和 CategoryModel 之间的多对多关系)。其中的一个片段是:
public class CategoryModel
{
[Key]
public int id { get; set; }
public string Name {get; set; }
public virtual ICollection<App_CategoryModel> mapping { get; set; }
}
public class AppModel
{
[Key]
public int id { get; set; }
public string Name { get; set; }
public virtual ICollection<App_CategoryModel> mapping { get; set; }
}
public class App_CategoryModel
{
[Key]
public int id {get; set;}
public int AppId {get; set; }
public int CategoryId {get; set; }
public virtual AppModel App {get; set;}
public virtual CategoryModel Category {get; set;}
}
我遵循 'Code-first' 方法并且 table 已成功创建。但是,现在我被困在如何填充和显示这些信息上。
我有以下作为输入数据:
List<AppModel>
List<CategoryModel>
和 Dictionary<"appname", List<CategoryModel>>
我如何从这里继续,以便我可以更新映射 table?
另外,想了解这是否是表示数据的正确方法。由于一个应用程序可以有多个类别 - 我希望输出是唯一应用程序的集合以及每个应用程序的类别列表,例如:
Dictionary<AppModel, List<CategoryModel>>
编辑: 这是我根据 smoksnes-
的建议尝试的 List<CategoryModel> cat_list = new List<CategoryModel>();
CategoryModel c1 = new CategoryModel();
c1.Name = "string1";
cat_list.Add(c1);
CategoryModel c2 = new CategoryModel();
c2.Name = "string2";
cat_list.Add(c2);
List<AppModel> app_list = new List<AppModel>();
AppModel a1 = new AppModel();
a1.Name = "app1";
app_list.Add(a1);
AppModel a2 = new AppModel();
a2.Name = "app2";
app_list.Add(a2);
a1.mapping.Add(c1);
a1.mapping.Add(c2);
a2.mapping.Add(c1);
a2.mapping.Add(c2);
db.categories.AddRange(cat_list);
db.apps.AddRange(app_list);
db.SaveChanges();
此后,EF 正常工作 - 2 个类别、2 个应用程序和 4 个映射条目 table。
虽然这有效,但不确定是谁阻止 EF 为类别创建 4 个条目?
正如您在评论中提到的 Barry O´Kane 一样,没有理由保留 App_CategoryModel
模型。 EF 将为您管理。只有当它包含有关两个表之间关系的任何额外信息时,才应保留它。但根据你的例子,没有理由保留它。
public class CategoryModel
{
public CategoryModel()
{
AppModels = new List<AppModel>();
}
[Key]
public int id { get; set; }
public string Name {get; set; }
public virtual ICollection<AppModel> AppModels { get; set; }
}
public class AppModel
{
public AppModel()
{
// Not sure if this is actually needed anymore. But EF usually adds it.
CategoryModels = new List<CategoryModel>();
}
[Key]
public int id { get; set; }
public string Name { get; set; }
public virtual ICollection<CategoryModel> CategoryModels { get; set; }
}
关于你关于代表的问题,我认为没有必要。由于 AppModel
已经在其模型上连接了 CategoryModel
,因此没有理由 Dictionary
。您可以将其存储在 List<AppModel>
中。
IList<AppModel> myApps = context.AppModels.ToList();
foreach (var myApp in myApps)
{
Console.Writeline("App {0} has the following categories:", myApp.id);
foreach (var category in myApp.CategoryModels)
{
Console.Writeline(category.Name);
}
}
当您想向应用添加类别时:
// I don't know how you create your Context, so below it's just called context.
var newCategoryModel = new CategoryModel
{
Name = "SO is awesome!"
};
var appModel = context.AppModels.FirstOrDefault(x => x.id == 1);
appModel.CategoryModels.Add(newCategoryModel); // EF will automatically set foreign keys for you...
context.SaveChanges();
如果你想确保没有类别被添加两次:
public void AddCategory(int appId, string categoryName)
{
using(var context = new DbContext())
{
var category = context.CategoryModels.FirstOrDefault(x => x.Name == categoryName);
if(category == null)
{
// Only create new CategoryModel if it doesn't exist.
category = new CategoryModel
{
Name = categoryName
};
}
var appModel = new AppModel
{
id = appId
};
// Attach to save on db-trip
context.AppModels.Attach(appModel);
//TODO: Possibly check if this particular appModel already has this category?
appModel.CategoryModels.Add(category);
context.SaveChanges();
}
}