2017-10-06 3 views
0

を関連付けると、複数の親タイプからオブジェクト、および取得子供たち、そして</p> <p>に最も効率的な方法は何ですかA)すべての子を取得ゼム

b)は親タイプが何であるかを知っていると各子供の正確な親のID?

現在のところ、これは私がやっていることであり、それは信じられないほど非効率的です。少なくとも、各子供の特定の親を見つける部分です。

public class ChildModel 
{ 
    public int Id { get; set; } 
    public string Name { get; set; } 
} 

public class ParentType1Model 
{ 
    public int Id { get; set; } 
    public string Name { get; set; } 
    public virtual ICollection<ChildModel> Children { get; set; } 
} 

public class ParentType2Model 
{ 
    public int Id { get; set; } 
    public string Name { get; set; } 
    public virtual ICollection<ChildModel> Children { get; set; } 
} 

//Get all ChildModels from ParentType1 
var parentType1Children = db.ParentType1Models 
    .SelectMany(x => x.Children) 
    .ToList(); 

listOfChildModels.AddRange(parentType1Children); 

//Get all ChildModels from ParentType2 
var parentType2Children = db.ParentType2Models 
    .SelectMany(x => x.Children) 
    .ToList(); 

listOfChildModels.AddRange(parentType2Children); 


//Find the parent for each ChildModel 
foreach (var child in listOfChildModels) 
{ 
    ParentType1Model parentType1ModelCheck = null; 
    ParentType2Model parentType2ModelCheck = null; 

    parentType1ModelCheck = await db.ParentType1Models 
     .Where(p => p.Children 
     .Any(i => i.Id == child.Id)) 
     .FirstOrDefaultAsync(); 

    //If first check is null, then move to second check 
    if (taskProjectModelCheck == null) 
    { 
     parentType2ModelCheck = await db.ParentType2Models 
      .Where(p => p.Children 
      .Any(i => i.Id == child.Id)) 
      .FirstOrDefaultAsync(); 
    } 

    //Now record the parent type and parent Id in an object containing the original ChildModel and it's parent's info (to be used later for various things) 
    ChildViewModel childViewModel = new ChildViewModel(); 
    childViewModel.ChildModel = child; 
    if (parentType1ModelCheck != null) 
    { 
     childViewModel.ParentType = "ParentType1"; 
     childViewModel.ParentModelId = parentType1ModelCheck.Id; 
    } 

    else if (parentType2ModelCheck != null) 
    { 
     childViewModel.ParentType = "ParentType2"; 
     childViewModel.ParentModelId = parentType2ModelCheck.Id; 
    }   
} 

答えて

0

私は生のSQLを使用して終了し、非常に高速です。 データベースに対して直接クエリを書くことで、ParentTypeXModelsとChildModelsを設定するときに、Entity Frameworkによって作成される多対多リレーションシップテーブルに直接アクセスできました。

result = dbContext.Database.SqlQuery<ANewChildObject>(
"select 
    ParentModelId = pm.Id, 
    Id = c.Id, 
    ParentType = 'ParentType1' 
from dbo.ChildModels c 
    JOIN dbo.ParentType1ModelsChildModels pmT ON c.Id = pmT.ChildModel_Id 
    JOIN dbo.ParentType1Models pm on pmT.ParentType1Model_Id = pm.Id 

UNION ALL 

select 
    ParentModelId = pm.Id, 
    Id = c.Id, 
    ParentType = 'ParentType2' 
from dbo.ChildModels c 
    JOIN dbo.ParentType2ModelsChildModels pmT ON c.Id = pmT.ChildModel_Id 
    JOIN dbo.ParentType2Models pm on pmT.ParentType2Model_Id = pm.Id" 
).ToList(); 
1

どうすればよいですか?

var ids1 = from p in db.ParentType1Models 
      from c in p.Children 
      select new 
      { 
       parentId = p.Id, 
       parentName = p.Name, 
       childName = c.Name, 
       childId = c.Id, 
       ParentType = "One" 
      }; 


var ids2 = from p in db.ParentType2Models 
      from c in p.Children 
      select new 
      { 
       parentId = p.Id, 
       parentName = p.Name, 
       childName = c.Name, 
       childId = c.Id, 
       ParentType = "Two" 
      }; 

var results = ids1.Union(ids2).ToList(); 
+0

このコードを簡略化して短縮しましたが、最終的には応答時間の約3倍を追加しました。 – amartin

+1

@amartinそれは残念です。私はデモンストレーションの名前を含めました。たぶんIDだけに限定すると、インデックスにヒットする可能性があります。クエリプランを見ずに知りにくい。 – Rob

+0

私はあなたが正しいと思いますが、残念ながら私はChildModelsの多くのプロパティが必要です。 – amartin

関連する問題