【问题标题】:Problem getting same result from DataContext.Translate从 DataContext.Translate 获得相同结果的问题
【发布时间】:2011-09-21 21:04:15
【问题描述】:

这个问题是这个问题的后续: 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 为空

原始查询在 SQLServer2000 上运行非常慢,我在更改数据类型时修复了它(Linq 使用 nvarchar 和小数,因为我的数据库使用 varchar 和数字)

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

有没有想过在这里得到相同的结果?

我也尝试过匿名类型,像这样:

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

但结果是一样的:

【问题讨论】:

    标签: linq anonymous-types translate strong-typing


    【解决方案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和你自定义的版本有什么区别?除非它进行一些转换,否则我不希望这种类型的查询需要优化。

    【讨论】:

    • 区别在于数据类型。出于某种原因,nvarchar 和 decimal 在具有 varchar 和 numeric 数据类型的 SQL2000 基础上运行得不是很好。我搜索了不同的论坛,发现其他有类似问题的论坛。
    【解决方案2】:

    我会使用AsEnumerable extension method,它基本上将IQueryable 转换为IEnumerable,从而强制处理枚举数。您可以通过调用ToArray()ToList() 来实现相同的目的,但AsEnumerable() 神奇地让您通过调用AsQueryable() 将其返回到IQueryable

    所以可能执行以下操作对您有用:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-05-12
      • 2013-12-16
      • 1970-01-01
      • 1970-01-01
      • 2021-02-19
      • 1970-01-01
      • 2013-08-22
      • 2021-02-17
      相关资源
      最近更新 更多