这个问题是对这个问题的跟进: 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},
}
但结果是一样的:
答案 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 },
}
});