2016-08-15 55 views
8

這是自從轉移到EF 6以來,一直困擾着我的東西。我們現在如何映射集合以查看模型,以便使用IEnumerables映射更改不會很痛苦。這是下面展示我的問題的代碼片段:將EF實體映射到維護ICollection和延遲加載的ViewModels

實體 - SS.Entity.Event

[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")] 
public virtual ICollection<SS.Entity.User> Broadcasters { get; set; } 
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")] 
public virtual ICollection<SS.Entity.User> Viewers { get; set; } 

模式 - SS.Model.Event

public virtual ICollection<SS.Model.User> Broadcasters { get; set; } 
public virtual ICollection<SS.Model.User> Viewers { get; set; } 

映射回收藏品修改後的實體

Broadcasters = e.Broadcasters.Select(u => new SS.Entity.User 
{ 
    Id = u.Id, 
    SkypeId = u.SkypeId, 
    Name = u.Name 
}).ToList(), // THIS IS THE PROBLEM 
Viewers = e.Viewers.Select(u => new SS.Entity.User 
{ 
    Id = u.Id, 
    SkypeId = u.SkypeId, 
    Name = u.Name 
}).ToList() // THIS IS THE PROBLEM 

這樣做的問題是我無法將ICollection映射到另一個ICollection,因爲Select會生成一個IEnumerable,這使得將屬性映射回EF之後非常痛苦,因爲我必須重新創建集合或枚舉集合來更新它。我知道我錯過了一些顯而易見的東西,我已經更新了ICollection的虛擬其他答案中概述的內容,但是我不清楚這有什麼用處。

任何幫助將不勝感激!

傑拉德

+0

爲什麼不'廣播= e.Broadcasters'?這是很不清楚你問的。是否有一個「用戶」類,或兩個?那麼如何延遲加載與此有關? –

+0

我試圖通過添加命名空間來使其更加清晰。基本上我的問題是如何映射回EF6中的集合更改。沒有ToList(),我發現沒有明確的方法可以做到這一點。因此,在處理大型集合時會有明顯的性能下降。 –

+0

「....通過映射集合來查看模型,以便使用IEnumerables映射變回不會很痛苦」......這並不明確。 「通過地圖集合」意味着什麼?正如你的帖子所說,你正在從你的DTO創建新的類型.....爲什麼這不適合你? – Sam

回答

1

在您的視圖模型,他們可以只是IEnumerable<T>,除非以後需要做對他們.Add()。這可以是任何你想成爲的。此外,他們不必在模型上虛擬,因爲您沒有EF創建模型的派生類型(再次,除非您有其他原因)。

要將它們重新設置爲DTO對象中的內容,如果您只是想直接設置而不檢查單個屬性,則可以使用.ToList()使其滿足ICollection<T>要求。

// Assuming "var model" is coming in as a parameter 
var station = context.Viewers.First(); 
station.Broadcasters = model.Broadcasters.Select(b => new User { 
    Id = b.Id, 
    SkypeId = b.SkypeId, 
    Name = b.Name 
}).ToList(); 
station.Viewers = model.Viewers.Select(v => new User { 
    Id = v.Id, 
    SkypeId = v.SkypeId, 
    Name = v.Name 
}); 
+0

這用於在EF6之前的版本中工作,但不再有效。甚至爲了映射而返回實體化新實體會導致爲每個更新創建新實體,而不僅僅是更新集合。 –

+0

另外ToList()枚舉集合,如果該集合很大會導致性能問題。 –

+0

無論如何,集合都將迭代。至少,你的問題很不清楚你的問題是什麼。現在EF6上沒有發生什麼情況發生在EF5中? – krillgar

2

假設你的 「.ToList()」 問題,同時節省回數據庫,這是你的尋找?:

var event = new SS.Entity.Event {Name = "New Name" and other properties}; 

IEnumerable<SS.Entity.User> broadcasters = e.Broadcasters 
     .Select(u => new SS.Entity.User 
      { 
       Id = u.Id, 
       SkypeId = u.SkypeId, 
       Name = u.Name 
      }); 

var viewers = e.Viewers.Select(u => 
      new SS.Entity.User 
      { 
      Id = u.Id, 
      SkypeId = u.SkypeId, 
       Name = u.Name 
      }); 

//add broadcasters to event 
event.Broadcasters.AddRange(broadcasters); 

//add viewers to event 
event.Viewers.AddRange(viewers); 

dataContext.Events.Add(event); 
dataContext.SaveChanges(); 
+0

這是一個好主意......我目前無法訪問代碼來嘗試一下,但明天讓我看看。添加範圍需要IEnumerable嗎? –

+0

@傑拉德 - 是的,它的確如此。 https://msdn.microsoft.com/en-us/library/system.data.entity.dbset.addrange(v=vs.113).aspx – Developer

+0

@GerardWilkinson對此有何好運? – Developer