2017-06-28 23 views
0

は私のデータベースで次のPOCOのを考えてみましょうLINQ to SQLはとマップされていないプロパティを設定するには:私は私のリポジトリから人々をフェッチするとき項目を選択し、

public class Person 
{ 
    [Key] 
    public Int32 PersonId { get; set; } 

    public String Name { get; set; } 

    public Collection<Pet> Pets { get; set; } 

    [NotMapped] 
    public Int32 NumberOfPets { get; set; } 
} 

public class Pet 
{ 
    [Key] 
    public Int32 PetId { get; set; } 

    public Int32 PersonId { get; set; } 

    public Person Person { get; set; } 

    public String Name { get; set; } 
} 

私はNumberOfPetsプロパティセットをしたいと思いますが、私はしたくありません暗黙のうちにペットに常に参加してください。

public class PersonRepository 
{ 
    public IList<Person> GetAllPeople1() 
    { 
     return _context.People.Select(x => { x.NumberOfPets = x.Pets.Count(); return x; }).ToList(); 
    } 
    public IList<Person> GetAllPeople2() 
    { 
     return _context.People.Select(x => new Person 
     { 
      NumberOfPets = x.Pets.Count(), 
      Name = x.Name 
     }).ToList(); 
    } 
    public IList<Person> GetAllPeople3() 
    { 
     var people = _context.People; 
     foreach (var p in people) 
     { 
      p.NumberOfPets = p.Pets.Count(); 
     } 
     return people.ToList(); 
    } 
} 

方法1は動作しますが、Linq to SQLでは動作しません。 #2は動作しますが、より多くのプロパティがPersonに追加されるとエラーが発生しやすくなります。ここに追加するのは忘れやすいでしょう。 #3は、たくさんのクエリを生成します。私は財布のSQLを使用してこれを達成する方法を知っていますが、効率的な方法で私の仕事をEFにする方法を明確にしていません。

(半)効率的なクエリを生成しているときに#1の動作をする構文はありますか?

答えて

1

#2よりも良い方法はないと思います(しかし、あなたが言ったように、それ自身の問題があります)。

いくつかの選択肢:

  1. はあなたが後にしているデータを表すビューを作成します。 Personに対して直接ではなく、ビューに対してクエリを実行します。
  2. 遅延読み込みを利用します。 NumberOfPetsを実装:がアクセスしたとき
  3. ここ

public int NumberOfPets { get { return Pets.Count(); } } 

NumberOfPetsはペットテーブルを照会します。あなたが望むなら、あなたはまた、いくつかのキャッシングで焼くことができます。

+0

確認していただきありがとうございます。私はすぐにToList()を実行するので、「Select count(*)from Pet」というN個のクエリは、毎回PetId = xxとなるでしょう... – sheamus