2016-05-09 1 views
0

Я изучаю Entity Framework в приложении asp.net mvc. У меня есть 3 модели -заполнить таблицу отношений многих-ко-многим, используя свойства навигации в Entity Framework

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

Я следовал «кодовому принципу», и таблицы были успешно созданы. Но теперь я застрял в том, как заполнять и отображать эту информацию. У меня есть следующие в качестве входных данных: List<AppModel> List<CategoryModel> и Dictionary<"appname", List<CategoryModel>>

Как перейти от здесь, так что я могу обновить таблицу сопоставления?

Кроме того, хотелось бы понять, является ли это правильным подходом к представлению данных. Поскольку приложение может иметь несколько категорий - Я ожидаю, что выход как набор уникальных Apps вместе со списком категорий для каждого приложения, что-то вроде:

Dictionary<AppModel, List<CategoryModel>> 

Edit: Это то, что я пытался в соответствии с предложение от 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 работал expeted - 2 категории, 2 приложений и 4 записей в таблице отображения.

Хотя это сработало, но не уверен, кто останавливает EF для создания 4 записей для категорий?

+1

вам нужно Д.О. Класс «App_CategoryModel» вообще? Если вы используете 'ICollection ' в 'CategoryModel' и' ICollection 'в' AppModel', EF не будет генерировать промежуточную таблицу? –

ответ

0

Точно так же, как 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(); 
    } 
} 
+0

Спасибо! попробует и обновит. В моем вопросе я не был четко сформулирован вопрос - у меня есть список категорий и список приложений, поэтому при таком подходе мне нужно сначала обновить категории в db, а затем использовать возвращаемые первичные ключи для обновления внутри приложений, а затем сохранить приложения в дБ. В противном случае, если несколько приложений имеют несколько категорий, у меня могут быть ненужные дубликаты в таблице категорий. – pankaj

+0

@pankaj, Да, вам придется обновлять свои таблицы своими данными.Но это решение ничем не отличается. Будут созданы те же таблицы базы данных. Это просто меньше кода для поддержки. Я также добавил пример функции, где вы можете добавить новую категорию, а также проверить, существует ли категория уже на основе имени. – smoksnes

+0

откуда вы получили это приложение? – pankaj