Как создать ассоциацию «многие ко многим» в Entity Framework Code - PullRequest
27 голосов
/ 23 ноября 2010

Я только начинаю работать с EF и смотрю несколько отличных обучающих видео. Я застрял со следующим.

У меня есть класс для коллекции файлов, я хотел бы, чтобы они были привязаны к событиям и / или людям

public class file{
    public int id {get;set;}
    public string path {get;set;}
}

public event {
    public int id {get;set;}
    public string eventname {get;set}
    public virtual ICollection<file> files {get;set;}
    public event(){ files = new list<file>();}
}

public person {
    public int id {get;set;}
    public string name {get;set}
    public virtual ICollection<file> files {get;set;}
    public person(){ files = new list<file>();}
}

Теперь, когда я генерирую базу данных, моя файловая таблица имеет PersonID AND EventID.

Я хочу, чтобы пользователи могли прикреплять файлы к людям и / или событиям.

1 Ответ

32 голосов
/ 23 ноября 2010

То, что вы получаете, - это поведение EF Code First по умолчанию с точки зрения сопоставления связи 1 со многими в базе данных.Например, у вас есть ICollection<File> для класса Person, в результате EF создаст таблицу FK для файлов (PersonId) и сопоставит ее с Id PK для таблицы Persons.

Теперь, я предполагаю, что вам нравится иметь отношение многие ко многим между Файлом и Лицом, так что каждый файл может относиться ко многим Людям, и у каждого Лица может быть много файлов (одинаковыхистория для объекта «Событие»).Один из способов добиться этого - поместить свойства навигации в класс File, указывающий на классы Event и Person.Итак, ваша модель должна быть изменена на следующее:

public class File {
    public int Id { get; set; }
    public string Path { get; set; }
    public virtual ICollection<Event> Events { get; set; }
    public virtual ICollection<Person> Persons { get; set; }
}

public class Event {
    public int Id { get; set; }
    public string EventName { get; set; }
    public virtual ICollection<File> Files {get;set;}
}

public class Person {
    public int Id { get; set; }
    public string Name { get; set; }
    public virtual ICollection<File> Files { get; set; }
}

public class MyContext : DbContext {
    public DbSet<Person> Persons { get; set; }
    public DbSet<Event> Events { get; set; }
    public DbSet<File> Files { get; set; }
}

В результате EF создаст таблицы ссылок (Events_Files и Files_Persons), чтобы сопоставить эти многочисленные и многие ассоциации с базой данных.

Обновление:
При использовании POCO с EF, если вы отметите свои навигационные свойства как virtual , вы включите некоторые дополнительные EF-поддержки, такие как Ленивая загрузка и Исправление отношений .Поэтому в общем случае виртуальные ключевые слова в свойствах навигации считаются хорошей практикой.

...