从DataContext.Translate获得相同结果的问题

时间:2011-06-24 09:00:41

标签: linq anonymous-types translate strong-typing

这个问题是对这个问题的跟进: How to create a list from two values

考虑以下代码:

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上运行非常慢,我在更改数据类型时修复了它(Linq使用nvarchar和decimal,因为我的数据库使用varchar和numeric)

所以我希望result2与result1相同,但是在执行像这样的DataContext.Translate时不会发生这种情况。

在这里得到相同结果的任何想法?

我也尝试过匿名类型,如下:

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

但结果是一样的:

2 个答案:

答案 0 :(得分:1)

我认为你对Translate的要求过高。

如果我理解正确,那么第一个查询(mainQuery)太慢了,所以我希望将其替换掉。

我会创建一个更简单的临时类,如

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

列表采用此格式后,您可以使用第二个查询将其更改为MainClass列表。

只是感兴趣,Linq输出的sql和你的自定义版本有什么区别?除非进行一些投射,否则我不希望这种类型的查询需要优化。

答案 1 :(得分:0)

我会使用AsEnumerable extension method基本上将IQueryable转换为IEnumerable,这会强制处理枚举数。您可以通过致电ToArray()ToList()来实现相同的目标,但AsEnumerable()可以让您通过致电IQueryable

将其恢复为AsQueryable()

因此,执行以下操作可能对您有用:

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 },
                  }
         });