从 DataContext.Translate 获得相同结果时出现问题
这个问题是这个问题的后续问题: 如何从两个值创建列表
考虑以下代码:
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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我认为你对 Translate 的要求太多了。
如果我理解正确的话,这是第一个查询(mainQuery)太慢,所以我想替换它。
我会创建一个更简单的临时类,例如
一旦列表采用这种格式,您可以使用第二个查询将其更改为 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
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.
我将使用 AsEnumerable 扩展方法它基本上将
IQueryable
转换为IEnumerable
,强制处理枚举器。您可以通过调用ToArray()
或ToList()
来实现相同的效果,但是AsEnumerable()
可以神奇地让您将其返回到IQueryable
通过调用AsQueryable()
因此,执行以下操作可能对您有用:
I would use the AsEnumerable extension method which basically converts the
IQueryable
to anIEnumerable
which forces the enumerator to be processed. You could achieve the same thing by callingToArray()
orToList()
butAsEnumerable()
magically lets you return it back to anIQueryable
by callingAsQueryable()
So probably doing the following will work for you: