views:

606

answers:

4

Hello,

I'm currently using Entity framework, and I want to perform a Linq query with a join on two columns, one being of type 'String', and the other of type 'Int32'.

Somethign similar to

from FirstEntity obj in context.FirstEntity 
                      join SecondEntity obj2 in context.SecondEntity on obj.SecondEntityId equals obj2.Id.ToString()

with obj.SecondEntityId as String and obj2.Id as Int32

Unfortunately, the ToString operation does not seen to be supported by EF. I get stuck with this error (or some similar errors, if I want to convert string to Int32):

LINQ to Entities does not recognize the method 'System.String ToString()' method

and until now, I was not able to find a work around.

Thx for any help.

A: 

In LINQ to SQL you can use Convert.ToString(obj2.Id), but it seems EF doesn't support that (see this thread on MSDN). However, you might be able to use a Model Defined Function.

Update: Since it doesn't seem an EF solution will work, I would just create a SQL View with your int field converted and whatever other fields you need. Or you could keep your existing entities and just join across a two-column view with the int and string IDs. The query optimizer should be able to figure out what you're doing to make the performance impact negligible.

dahlbyk
Indeed, the Convert.ToString does not work either.I've thrown a look at Model defined functions: actually, those would had solved my problem, if they wasn'nt planned for the 4.0 version (I have to use the 1.0 version shipped with fwk 3.5).
The view was the adopted solution, and it works flawlessly. thx.
A: 

We typically break something like this up into 2 queries (lack of ToString() in linq to entities support makes me want to harm small children).

var query1 = (from SecondEntity obj2 in context.SecondEntity
             select obj2.ID).ToList();

// now we're using linq to objects which does support ToString()
query1 = query1.Select(x => x.ToString());

// mixing linq to entities and linq to objects
var query2 = from FirstEntity obj in context.FirstEneity
             join SecondEntity obj2 in query1 on obj.SecondEntityId equals obj2.ID

I'm doing this without VS, so some of the syntax could be wrong and it's not a particularly nice solution, but EF is V1.

takobell
Actually, I've found some articles related to analog solutions, but I'm too concerned of the performance/memory consumption overhead. The tables are likely to contains lot of data, and those kind of tricks may result as OutOfMemory exceptions. If I don't find a solution related to EF, I would rather implement a solution on the db side (either as a Stored procedure, or add another field of the required type + a trigger).Anyway, thanks for the hint.
For what it's worth, we're doing multiple joins like this (although more selective in the data selection) against tables with 20+ million rows in them. As long as your indexes and statistics are setup properly, performance hasn't been an issue for us.
takobell
Actually our tables won't contains 20+ million rows :).As I stated yesterday, A view has been done, and this solution is OK: It gaves a more proper (or less dirty) design to the DB. Both columns contains Ids but due to "interop constraints with another software", we have to keep the string column... As soon as I get some spare time, I gonna test your solution. Just a thought: when you split your request into 2 qry, to perform the 2nd, you have to load the full result set of the 1st into memory. If the 1st returns a bunch of data, it may overload the memory available. Am I wrong ?
You're absolutely right. If it's a small amount of data it doesn't matter that much. If it's a large amount, you will want to try to limit query1 with a where clause if possible.Another options is do to this in a SPROC either EF mapped or drop down to ADO.NET.
takobell
A: 

Finally, I made a view based upon the table, with a new int field holding the converted string, on DB side. Then I mapped my EF entity to the view. It works :)

Sad I didn't find a proper solution on EF side. Hopefully, the 4.0 version will solve this kind of issues.

Anyway, thx for your help.

A: 

Does it help if you use the functional C# syntax instead of the special Linq syntax?

var results = FirstEntity.Join(SecondEntity, 
     obj => obj.SecondEntityId, obj2 => obj2.Id.ToString(), 
    (obj, obj2) => new { First = obj, Second = obj2 });
John Fisher