Saturday, 15 August 2015

.net - Identical (?) C# and VB.NET LINQ queries return different results -



.net - Identical (?) C# and VB.NET LINQ queries return different results -

probably easy, can't see it...

i replicating ms access query in linq. wrote in c# first test it, because prefer c#, translated vb.net syntax. far can tell 2 queries should identical, whilst c# query returns right results, vb.net 1 returns 0 results.

can see difference might be?

the c# query:

var table1 = dc.maintable.where(o => o.year == 423).tolist().select(o => new { key_id = o.key_id.value, cropid = o.cropid.value, groupid = o.groupid.value, surface1 = o.surface1.value, surface2 = o.surface2.value }); var table2 = dc.othertable.where(o => o.year == 423).tolist().select(o => new { key_id = o.key_id.value, cropid = int.parse(o.saku_cd), groupid = int.parse(o.san_dan_no), surface1 = convert.todouble(o.keihan_men.value), surface2 = convert.todouble(o.saku_men.value) }); var output = table1.join(table2, t1 => new { t1.key_id, t1.cropid, t1.groupid, t1.surface1, t1.surface2 }, t2 => new { t2.key_id, t2.cropid, t2.groupid, t2.surface1, t2.surface2 }, (t1, t2) => new outputdatatype() { key_id = t1.key_id, year = 423 }).tolist();

the vb.net query:

dim table1 = maintable.where(function(o) o.year.value = 423).tolist().select(function(o) new { .key_id = o.key_id.value, .cropid = o.cropid.value, .groupid = o.groupid.value, .surface1 = o.surface1.value, .surface2 = o.surface2.value }).tolist() dim table2 = othertable.where(function(o) o.year.value = 423).tolist().select(function(o) new { .key_id = o.key_id.value, .cropid = convert.toint32(o.saku_cd), .groupid = convert.toint32(o.san_dan_no), .surface1 = convert.todouble(o.keihan_men.value), .surface2 = convert.todouble(o.saku_men.value) }).tolist() dim output = table1.join(table2, function(t1) new { t1.key_id, t1.cropid, t1.groupid, t1.surface1, t1.surface2 }, function(t2) new { t2.key_id, t2.cropid, t2.groupid, t2.surface1, t2.surface2 }, function(t1, t2) new outputdatatype {.key_id = t1.key_id, .year = 423}).tolist()

in both c# , vb.net table1 , table2 same, must join fails.

edit

i changed join in vb.net query syntax, this:

dim output = t1 in maintable bring together t2 in othertable on t1.key_id equals t2.key_id , t1.groupid equals t2.groupid , t1.cropid equals t2.cropid , t1.surface1 equals t2.surface1 , t1.surface2 equals t2.surface2 select new outputdatatypedata {.key_id = t1.key_id, .year = 423}

which gives right result. don't how different extension method join syntax?

when utilize join extension method, keys provide outerkeyselector , innerkeyselector arguments compared using equals method.

but c# , vb.net handle anonymous types differently here:

c#

var = new {foo = 1, bar = 2 }; var b = new {foo = 1, bar = 2 }; bool result = a.equals(b); // true

vb.net

dim = new {.foo = 1, .bar = 2} dim b = new {.foo = 1, .bar = 2} dim result = a.equals(b) ' false '

what's happening here?

c# uses value equality compare 2 objects, comparing values of properties.

vb.net uses reference equality compare 2 objects, hence result false.

to have code work, have explicitly tell vb.net compare properties using key keyword:

key properties differ non-key properties in several fundamental ways:

only values of key properties compared in order determine whether 2 instances equal. the values of key properties read-only , cannot changed. only key property values included in compiler-generated hash code algorithm anonymous type. dim = new {key .foo = 1, key .bar = 2} dim b = new {key .foo = 1, key .bar = 2} dim result = a.equals(b) # true

the query syntax works because in case not comparing anonymous types/objects ints , doubles.

c# .net vb.net linq

No comments:

Post a Comment