从 DataContext.Translate 获得相同结果时出现问题

发布于 2024-11-17 08:42:38 字数 1678 浏览 4 评论 0原文

这个问题是这个问题的后续问题: 如何从两个值创建列表

考虑以下代码:

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 和十进制,因为我的数据库使用 varchar 和numeric)

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

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

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

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

但结果是相同的:

This question is a follow up to this question:
How to create a list from two values

Consider this code:

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

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

and:

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 is OK

result2.MainList is null

The original query was very slow running on SQLServer2000, and I got it fixed when changing datatypes (Linq uses nvarchar and decimal, as my database use varchar and numeric)

So I want result2 to be the same as result1, but that doesn't happen when doing a DataContext.Translate like this.

Any thoughts of getting the same result here?

I've also tryed anonymous types, like this:

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

but the result is the same:

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

最好是你 2024-11-24 08:42:38

我认为你对 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 和你定制的版本有什么区别?除非它进行一些转换,否则我不认为这种类型的查询需要优化。

I think you are asking too much from Translate.

If I understand you correctly, it is the first query (mainQuery) that is too slow, so I would look to replace it.

I would create a simpler temporary class like

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

Once the list is in this format, you can use the second query to change it to a list of MainClass.

Just a matter of interest, what is the difference between the sql outputted by Linq and your customized version? Unless it is does some casting, I would not expect this type of query to need optimizing.

烟雨凡馨 2024-11-24 08:42:38

我将使用 AsEnumerable 扩展方法它基本上将 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 },
                  }
         });

I would use the AsEnumerable extension method which basically converts the IQueryable to an IEnumerable which forces the enumerator to be processed. You could achieve the same thing by calling ToArray() or ToList() but AsEnumerable() magically lets you return it back to an IQueryable by calling AsQueryable()

So probably doing the following will work for you:

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 },
                  }
         });
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文