好的,我知道这是一个黑客,但这是一个微小的数据操作项目,我想玩。 ; - )
我一直认为编译器会检查C#程序中使用的所有匿名类型,如果属性相同,它只会在幕后创建一个类。
所以我想说我想用一些类型化的数据集创建一个匿名类型:
var smallData1 = new smallData1().GetData().Select(
x => new { Name = x.NAME, x.ADDRESS, City = x.CITY, State = x.STATE,
Zip = x.ZIP, Country = x.COUNTRY, ManagerName = x.MANAGER_NAME,
ManagerID = x.MANAGER_ID });
var smallData2 = new smallData2().GetData().Select(
x => new { x.Name, x.ADDRESS, x.City, x.State, x.Zip, x.Country,
x.ManagerName,x.ManagerID });
我现在可以做一些有趣的事情,比如 smallData2.Except(smallData1); 等,这一切都有效。
现在,如果我有一对更大的匿名类型怎么办?
var bigData1 = new BigAdapter1().GetData().Select(
x => new { x.FirstName, x.LastName, x.Address, x.City, x.State,
x.Zip, x.Country, x.Phone, x.Email, x.Website, x.Custom1, x.Custom2,
x.Custom3, x.Custom4, x.Custom5, x.Custom6, x.Custom7, x.Custom8, x.Custom9,
x.Custom10, x.Custom11, x.Custom12, x.Custom13, x.Custom14, x.Custom15,
x.Custom16, x.Custom17, x.Custom18, x.Custom19, x.Custom20, x.Custom21,
x.Custom22, x.Custom23, x.Custom24, x.Custom25, x.Custom26, x.Custom27,
x.Custom28, x.Custom29});
var bigData2 = new BigAdapter2().GetData().Select(
x => new { x.FirstName, x.LastName, x.Address, x.City, x.State, x.Zip,
x.Country, x.Phone, x.Email, x.Website, x.Custom1, x.Custom2, x.Custom3,
x.Custom4, x.Custom5, x.Custom6, x.Custom7, x.Custom8, x.Custom9, x.Custom10,
x.Custom11, x.Custom12, x.Custom13, x.Custom14, x.Custom15, x.Custom16,
x.Custom17, x.Custom18, x.Custom19, x.Custom20, x.Custom21, x.Custom22,
x.Custom23, x.Custom24, x.Custom25, x.Custom26, x.Custom27,
x.Custom28, x.Custom29});
现在,当我执行 bigData2.Except(bigData1); 时,编译器会抱怨:
Instance argument: cannot convert from
'System.Data.EnumerableRowCollection<AnonymousType#1>' to
'System.Linq.IQueryable<AnonymousType#2>'
为什么呢?属性太多,因此编译器决定优化它不值得吗?
谢谢!
答案 0 :(得分:2)
你试过吗
bigData2.Except(bigData1.AsQueryable());
我刚刚运行了一个包含40个属性和20,000,000行的LINQ示例,我没有遇到问题。
(不幸的是,尝试这不是LINQPad中的可折叠示例)
void Main()
{
Test t = new Test();
var a = Enumerable.Range(1,10000000).Select(i => new
{
t.T0, t.T1, t.T2, t.T3, t.T4, t.T5, t.T6, t.T7, t.T8, t.T9,
t.T10, t.T11, t.T12, t.T13, t.T14, t.T15, t.T16, t.T17, t.T18, t.T19,
t.T20, t.T21, t.T22, t.T23, t.T24, t.T25, t.T26, t.T27, t.T28, t.T29,
t.T30, t.T31, t.T32, t.T33, t.T34, t.T35, t.T36, t.T37, t.T38, t.T39,
});
Test2 t2 = new Test2();
var b = Enumerable.Range(1,10000000).Select(i => new
{
t2.T0, t2.T1, t2.T2, t2.T3, t2.T4, t2.T5, t.T6, t2.T7, t2.T8, t2.T9,
t2.T10, t2.T11, t2.T12, t2.T13, t2.T14, t2.T15, t2.T16, t2.T17, t2.T18, t2.T19,
t2.T20, t2.T21, t2.T22, t2.T23, t2.T24, t2.T25, t2.T26, t2.T27, t2.T28, t2.T29,
t2.T30, t2.T31, t2.T32, t2.T33, t2.T34, t2.T35, t2.T36, t2.T37, t2.T38, t2.T39,
});
a.Except(b).Dump();
}
class Test
{
public string T0 { get; set ;}
public string T1 { get; set ;}
public string T2 { get; set ;}
public string T3 { get; set ;}
public string T4 { get; set ;}
public string T5 { get; set ;}
public string T6 { get; set ;}
public string T7 { get; set ;}
public string T8 { get; set ;}
public string T9 { get; set ;}
public string T10 { get; set ;}
public string T11 { get; set ;}
public string T12 { get; set ;}
public string T13 { get; set ;}
public string T14 { get; set ;}
public string T15 { get; set ;}
public string T16 { get; set ;}
public string T17 { get; set ;}
public string T18 { get; set ;}
public string T19 { get; set ;}
public string T20 { get; set ;}
public string T21 { get; set ;}
public string T22 { get; set ;}
public string T23 { get; set ;}
public string T24 { get; set ;}
public string T25 { get; set ;}
public string T26 { get; set ;}
public string T27 { get; set ;}
public string T28 { get; set ;}
public string T29 { get; set ;}
public string T30 { get; set ;}
public string T31 { get; set ;}
public string T32 { get; set ;}
public string T33 { get; set ;}
public string T34 { get; set ;}
public string T35 { get; set ;}
public string T36 { get; set ;}
public string T37 { get; set ;}
public string T38 { get; set ;}
public string T39 { get; set ;}
}
class Test2
{
public string T0 { get; set ;}
public string T1 { get; set ;}
public string T2 { get; set ;}
public string T3 { get; set ;}
public string T4 { get; set ;}
public string T5 { get; set ;}
public string T6 { get; set ;}
public string T7 { get; set ;}
public string T8 { get; set ;}
public string T9 { get; set ;}
public string T10 { get; set ;}
public string T11 { get; set ;}
public string T12 { get; set ;}
public string T13 { get; set ;}
public string T14 { get; set ;}
public string T15 { get; set ;}
public string T16 { get; set ;}
public string T17 { get; set ;}
public string T18 { get; set ;}
public string T19 { get; set ;}
public string T20 { get; set ;}
public string T21 { get; set ;}
public string T22 { get; set ;}
public string T23 { get; set ;}
public string T24 { get; set ;}
public string T25 { get; set ;}
public string T26 { get; set ;}
public string T27 { get; set ;}
public string T28 { get; set ;}
public string T29 { get; set ;}
public string T30 { get; set ;}
public string T31 { get; set ;}
public string T32 { get; set ;}
public string T33 { get; set ;}
public string T34 { get; set ;}
public string T35 { get; set ;}
public string T36 { get; set ;}
public string T37 { get; set ;}
public string T38 { get; set ;}
public string T39 { get; set ;}
}
答案 1 :(得分:2)
是的。它不是属性的数量。您的适配器返回完全相同的数据类型有多确定?
答案 2 :(得分:1)
匿名类型与任何类型一样,作用于其包含程序集。如果两个适配器在同一个dll中(实际上是模块IIRC),编译器只能视为相等。
除此之外,我会检查类型......
static Type Identify<T>(IEnumerable<T>) {return typeof(T);}
...
var t1= Identify(bigData1), t2= Identify(bigData2);
if(t1 == t2) {
Console.WriteLine("they're the same");
} else {
var props1 = t1.GetProperties(), props2 = t2.GetProperties();
if(props1.Length != props2.Length) {
Console.WriteLine(props1.Length + " vs " + props2.Length);
} else {
Array.Sort(props1, p => p.Name);
Array.Sort(props2, p => p.Name);
for(int i = 0 ; i < props1.Length ; i++) {
if(props1[i].Name != props2[i].Name)
Console.WriteLine(props1[i].Name + " vs " + props2[i].Name);
if(props1[i].PropertyType != props2[i].PropertyType)
Console.WriteLine(props1[i].PropertyType + " vs " + props2[i].PropertyType );
}
}
}