2014-03-31 71 views
0

我目前有一個使用實體框架的對象模型,其中包含一個屬性是一個列表的複雜對象。我把它存儲在數據庫與這裏提出的第二個選項:Representing a list in a SQL databasec#如何填充一個複雜的對象包含一個列表與sql

但總結:

Person() 
{ 
    long Id;//primary key 
    string Name; 
    List<long> ResponsibleFor; //list of id  
} 

被存儲爲2個以下表格

Persons: 
Id, 
Name 

Responsibilities: 
Id, 
PersonId, 
ResponsibleForId 

現在我有點爲難以及如何重新填充Person對象。我目前的做法如下:

from p in db.Persons 
join r in db.Responsibilities on p.Id equals r.PersonId 
where p.Id == IdImSearchingFor 
select new Person 
{ 
    Id = p.Id 
    ResponsibileFor = ? 
} 

而我卡住試圖重新填充List屬性。

有什麼建議嗎?

謝謝!

回答

1

您需要組的加入讓所有的人都負責的結果。

嘗試

var result = from p in db.Persons 
      join r in db.Responsibilities on p.Id equals r.PersonId 
      where p.Id == IdImSearchingFor 
      group r.ResponsibleForId by p into g 
      select new Person 
      { 
       Id = g.Key.Id, 
       Name = g.Key.Name, 
       ResponsibleFor = g.ToList() 
      }; 
+0

這可能會起作用,但將g分組似乎會失去Person的其他元素(例如名稱,但實際上更多)。有沒有一種方法可以進行不同的分組,以便我可以獲得p的所有元素,然後從r中獲取列表? – Norrec

+0

@Norrec您可以使用dbPersons中的整個對象作爲關鍵字進行分組,然後使用它的屬性。我編輯了我的答案。 – okrumnow

+0

我最終通過我的解決方案實施了您的解決方案,因爲它更加清潔。謝謝! – Norrec

0

假設你想要得到的人ID爲1的話..

from p in db.Persons 
join r in db.Responsibilities on p.Id equals r.PersonId 
where p.Id == 1 
select new Person 
{ 
    Id = p.Id 
    ResponsibileFor = p.ReponsibleFor 
} 
+0

這將工作除我使用EF和p.ResponsibleFor是自動生成的類型和不的。 – Norrec

0

檢查這一個。我測試過它會正常的類和列表,而不是EF或任何其他ORM。

以下是階級結構我已經明白

class Person 
{ 
    public long Id;//primary key 
    public string Name; 
} 

class Responsibility 
{ 
    public long Id;//primary key 
    public long PersonId; 
    public long ResponsibleForId; 
} 

以下是2測試列表

List<Person> Persons = new List<Person>() { new Person() { Id = 1, Name = "Samar" } }; 
List<Responsibility> Responsibilities = new List<Responsibility>() { new Responsibility() { Id = 1, PersonId = 1, ResponsibleForId = 1 }, new Responsibility() { Id = 2, PersonId = 1, ResponsibleForId = 2 } }; 

以下是查詢

var allPeople = from p in Persons 
       join r in Responsibilities on p.Id equals r.PersonId into g 
       where p.Id == 1 
       select new 
       { 
        Id = p.Id, 
        ReponsibleFor = g.Select(x => x.ResponsibleForId).ToList() 
       }; 

希望這是什麼你正在尋找。

+1

出於某種原因,此g.Select(x => x.ResponsibleForId).ToList()會引發異常: 「類型'System.Data.Entity.Infrastructure.ObjectReferenceEqualityComparer'的表達式不能用於類型的構造函數參數'System.Collections.Generic.IEqualityComparer'1 [System.Int64]'」 – Norrec

0

儘管大家以前的答案對我有幫助(謝謝!),但他們並沒有完全工作。所以我想我會在這裏添加我的解決方案,即使用聯合,分組和嵌套選擇的組合。

from p in db.Persons 
where p.Id == IdImSearchingFor 
join r in db.Responsibilities on p.Id equals r.ParentId into pr 
select new Person 
{ 
    Id = p.Id, 
    name = p.Name, 
    ResponsibleFor = (from a in pr 
         where a.ParentId == IdImSearchingFor 
         select new Person 
         { 
          Id = a.Id 
         }).ToList<Person>() 
} 
0

我的建議是使用懶惰加載模式來獲取您的列表,它可能會更好地執行和縮放。用你的例子。

public class Person() 
{ 
    public long Id { get; set; } 
    public string Name { get; set;} 
    private Lazy<List<long>> _responsibleFor; 
    public List<long> ResponsibleFor 
    { 
    get { return _responsibleFor.Value; } 
    } 

    public void SetResponsibleFor(Func<long, List<long>> getResponsibleFor) 
    { 
    _responsibleFor = new Lazy<List<long>>(() => getResponsibleFor(Id)); 
    } 

    public Person():base() { } 
    public Person(long id, string name) 
    { 
    Id = id; 
    Name = name 
    } 

} 

    // Implementation 
    var p = new Person(1,"John Doe"); 
    p.SetResponsibleFor(GetResponsibleForPerson); //Pass a function/method which takes the long for input parameter and outputs List<long> 
相關問題