2014-11-04 7 views
0

У меня есть эти три сущности:Entity Framework отношения

public class Dog 
{ 
    public int DogId { get; set; } 
    public string Name { get; set; } 
    public int Age { get; set; } 
    public bool Checked { get; set; } 
    public string DogImage { get; set; } 

    public virtual ICollection<Result> Results { get; set; } 
} 

public class Event 
{ 
    public int EventId { get; set; } 
    public string EventName { get; set; } 
    public string EventLocation { get; set; } 
    public string EventType { get; set; } 
    public string EventDate { get; set; } 

    public virtual ICollection<Result> Results { get; set; } 
} 

public class Result 
{ 
    public int ResultId { get; set; } 
    public int Track { get; set; } 
    public int Obedience { get; set; } 
    public int Protection { get; set; } 

    [ForeignKey("Dog")] 
    public int DogId { get; set; } 
    public virtual Dog Dog { get; set; } 

    [ForeignKey("Event")] 
    public int EventId { get; set; }  
    public virtual Event Event { get; set; } 
} 

I've получал помощь от сюда до того, чтобы установить его, как это. Entity Framework errors when trying to create many-to-many relationship

Так как сейчас я думаю, result это «клей», который связывает эти классы вместе, содержащие внешние ключи к двум другим таблицам.

То, что я пытался достичь в течение нескольких дней в настоящее время является:

  1. Создать событие.
  2. Добавить собак к мероприятию.
  3. Добавить результаты для собак, участвующих в choosenEvent.

Допустим, я создаю событие так:

[HttpPost] 
public ActionResult CreateEvent(Event newEvent) 
{ 
    newEvent.EventDate = newEvent.EventDate.ToString(); 
    _ef.AddEvent(newEvent); 

    return View(); 
} 

Теперь я предполагаю, что следующий шаг должен был бы добавить список собак к этому событию, и для того, чтобы сделать это мне нужно каким-то образом использовать мой класс результатов, так как это класс «клей». Пожалуйста, дайте мне знать, если я даже на правильном пути.

+0

не было бы лучше для события содержать ICollection ? Затем собака будет содержать свой результат, чтобы вы могли сортировать собак по порядку. Также Dog может содержать ICollection , поскольку собаки могут появляться в нескольких событиях. – SWilko

ответ

1

Это не очень хорошая идея, чтобы сделать многие ко многим отношений, как, как вы сделали. See here

Для того, чтобы получить правильные отношения многих ко многим, отображается надлежащим образом в базе данных, которая не имеет ошибок, я хотел бы попробовать это так:

public class Dog {} 
public class Event {} 

public class Result {} 

// This is a linking table between Dog and Results 
public class DogResult 
{ 
    public int Id {get;set;} 
    public int DogId {get;set;} 
    public int ResultId {get;set;} 
} 

// This is a linking table between Events and Results 
public class EventResult 
{ 
    public int Id {get;set;} 
    public int EventId {get;set;} 
    public int ResultId {get;set;} 
} 

Когда вы сейчас пишете ваш запрос вы можете сделать это:

using (var context = new DbContext()) 
{ 
    var dogs = context.Dogs(); 
    var dogResults = context.DogResults(); 
    var results = context.Results(); 

    var dogsAndResults = dogs.Join(
      dogResults, 
      d => d.Id, 
      r => r.DogId, 
      (dog, dogResult) => new { dog, dogResult }) 
     .Join(
      results, 
      a => a.dogResult.ResultId, 
      r => r.Id, 
      (anon, result) => new { anon.dog, result }); 
} 

это немного противно смотреть, но это даст вам обратно список анонимных объектов, содержащих Dog и связанные с ним Result. Но, очевидно, было бы лучше сделать это в хранимая процедура:

using (var context = new DbContext()) 
{ 
    var results = context.Database.ExecuteStoreQuery<SomeResultDto>("SELECT * .... JOIN ... "); 
} 

Это чище, потому что вы используете SQL.

Это более сложный способ борьбы с ним. Но гораздо более эффективный, особенно если вы полностью понимаете, как инфраструктура entity выполняет LINQ.

Очевидно, что если вы хотите, чтобы создать эти ссылки:

using (var context = new DbContext()) 
{ 
    context.Dogs.AddRange(dogs); // dogs being a list of dog entities 
    context.Results.AddRange(results); // events being a list of results entities 

    context.DogResults.AddRange(dogResults); // a list of the links 
} 

Это полностью зависит от вас, как вы создаете эти ссылки. Чтобы превратить это в sproc, вы хотите создать некоторые пользовательские типы таблиц, определенные пользователем, и использовать их в качестве параметра значения таблицы.

var dogResults = dogs.SelectMany(d => results.Select (r => new DogResult { DogId = d.Id, ResultId = r.Id })); 

Это зверь запроса LINQ, и в основном он получает каждую собаку и связывает ее с каждым результатом. Запустите его в LinqPad и Dump значения.

+0

Большое спасибо, я попытаюсь изучить это и посмотреть, могу ли я это понять. Благодаря! – user2915962

+0

Но вы имеете в виду, что я должен оставить свои классы как есть и просто добавить два новых класса? Dogresult и Eventresult? Или я должен внести другие изменения и в других моих трех классах? – user2915962

+0

просто добавьте два дополнительных класса, оставьте остальных как есть! Помимо необходимости удалить свойства навигации. –

1

Я только делал это с использованием свободного метода (когда я учился, я обнаружил, что вы можете делать все свободно, но не с аннотациями, поэтому я не изучал их), следующее создает много-много между моей Unit сущности и моего UnitService лица:

modelBuilder.Entity<Unit>() 
      .HasMany<UnitService>(u => u.Services) 
      .WithMany(us => us.Units); 

Этот код находится в методе protected override void OnModelCreating(DbModelBuilder modelBuilder).

В вашем случае Event является Unit и Dog является UnitService.

О Упсе, вам не нужно, что на всех, ваша «присоединиться к» таблица вашей таблица результатов, в моем случае я не забочусь о присоединиться к таблице поэтому его всем скрытой. Может быть что-то вроде:

modelBuilder.Entity<Result>() 
       .HasMany<Event>(e => e.Results); 
    modelBuilder.Entity<Result>() 
       .HasMany<Dog>(d => d.Results); 
Смежные вопросы