0

この質問は、この質問のフォローアップです: 2 つの値からリストを作成する方法

次のコードを検討してください。

class MainClass() 
{
   string MainKey {get;set;}
   string MainName {get;set;}
   IEnumerable<SmallObject> MainList {get;set} 
}

class SmallObject() 
{
   string SmallKey {get;set} 
} 

と:

var mainQuery = (from v from DataContext.myTable
                 select v);

var myQuery = (from v in mainQuery
               select new MainClass()
               {
                  MainKey = v.Field1,
                  MainName = v.Field2,
                  MainList = new []
                  {
                     new SmallObject { SmallKey = v.Field3 },
                     new SmallObject { SmallKey = v.Field4 },
                  }
                });


var result1 = myQuery.ToList();

//Changing datatypes for optimization reasons in SQLServer2000
var cmd = DataContext.GetCommand(myQuery);
foreach (System.Data.Common.DbParameter param in cmd.Parameters)
{
  // nvarchar -> varchar
  // decimal -> numeric
}
var result2 = DataContext.Translate<MainClass>(cmd.ExecuteReader()).ToList();

result1.MainList は問題ありません

result2.MainList が null です

元のクエリは SQLServer2000 での実行が非常に遅く、データ型を変更すると修正されました (私のデータベースは varchar と numeric を使用するため、Linq は nvarchar と decimal を使用します)。

したがって、result2 を result1 と同じにしたいのですが、このように DataContext.Translate を実行すると、それは起こりません。

ここで同じ結果が得られるという考えはありますか?

次のように、匿名型も試しました。

IEnumerable<object> MainList {get;set;}
...
MainList = new []
{
   new { SmallKey = v.Field3},
   new { SmallKey = v.Field4},
}

しかし、結果は同じです:

4

2 に答える 2

1

あなたは翻訳からあまりにも多くを求めていると思います。

私があなたを正しく理解しているなら、それは遅すぎる最初のクエリ(mainQuery)なので、私はそれを置き換えることを検討します。

次のような単純な一時クラスを作成します

 public class TmpClass
 {
    public string Field1 {get;set;}
    public string Field2 {get;set;}
    public string Field3 {get;set;}
    public string Field4 {get;set;}
 } 

リストがこの形式になったら、2番目のクエリを使用して、リストをMainClassのリストに変更できます。

興味深いことに、Linqによって出力されるSQLとカスタマイズされたバージョンの違いは何ですか?キャストを行わない限り、このタイプのクエリを最適化する必要はないと思います。

于 2011-06-24T13:24:18.247 に答える
0

基本的に、列挙子を強制的に処理するに変換するAsEnumerable 拡張メソッドを使用します。を呼び出すことで同じことを達成できますが、魔法のように呼び出すことで元に戻すことができますIQueryableIEnumerableToArray()ToList()AsEnumerable()IQueryableAsQueryable()

したがって、おそらく次のことを行うとうまくいくでしょう:

var result1 = DataContext.myTable.AsEnumerable()
  .Select(v=> new MainClass {
                  MainKey = v.Field1,
                  MainName = v.Field2,
                  MainList = new []
                  {
                     new SmallObject { SmallKey = v.Field3 },
                     new SmallObject { SmallKey = v.Field4 },
                  }
         });
于 2011-06-24T13:38:36.793 に答える