2014-11-04 218 views
0

我有這三個實體:實體框架的關係

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

從來就被從這裏以設置它像這樣得到幫助之前。 Entity Framework errors when trying to create many-to-many relationship

所以現在我猜0123,是將這些包含外鍵的類連接到另外兩個表的「膠水」。

我一直在努力,現在實現了天是:

  1. 創建活動。
  2. 添加狗的事件。
  3. 將結果添加到參與choosenEvent的狗中。

可以說,我創建這樣一個事件:

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

    return View(); 
} 

現在我想,下一步將是狗的列表添加到此事件中,爲了做到這一點,我需要以某種方式使用我的結果類,因爲這是「膠水」級。請讓我知道,如果我在這裏的正確軌道。

+0

如果事件包含ICollection 會更好嗎?然後狗將包含它的結果,所以你可以通過事件排序狗。狗也可以包含ICollection ,因爲狗可以出現在多個事件中。 – SWilko 2014-11-04 09:40:11

回答

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,因此這更乾淨。

這是一個更復雜的處理方式。但性能要高得多,特別是如果你完全理解實體框架如何執行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 2014-11-04 09:36:30

+0

但是你的意思是我應該離開我的班級,只需添加兩個新班級? Dogresult和Eventresult?或者我還需要在其他三個班級中進行其他更改? – user2915962 2014-11-04 09:43:01

+0

只需添加兩個額外的類,讓其他人保持原樣!除了你需要刪除導航屬性。 – 2014-11-04 13:22:25

1

我只使用流利的方法做了這個(當我學習時,我發現你可以做一切流利的事情,但沒有註釋,所以我沒有看過他們),下面創建了多對多

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

此代碼是在protected override void OnModelCreating(DbModelBuilder modelBuilder)方法:我Unit實體和我UnitService實體之間。

在你的情況EventUnitDogUnitService

哦ooops,你根本不需要這個,你的'join'表就是你的結果表,在我的情況下,我不關心連接表,所以它全部隱藏起來。 也許是這樣的:

modelBuilder.Entity<Result>() 
       .HasMany<Event>(e => e.Results); 
    modelBuilder.Entity<Result>() 
       .HasMany<Dog>(d => d.Results);