I have two database tables:
- ‘MyTable’ which has a standard auto-incrementing primary key integer field.
- ‘UserAccess’ table is a mapping table that contains links to all systems via a composite key join.
MyTable:
ID int
IsDeleted bit
Email varchar(255)
UserAccess:
UserID guid
ProviderID int
ProviderUserID varchar(255)
Both tables are set up in my application via Entity Framework 4.1 Code First.
The primary table (my system/provider) has its own ID (e.g. 42). It can find if a user has access by finding if they have a record in the table for the ProviderID of 42.
My problem comes when trying to find out who a particular record in MyTable belongs to by mapping the ProviderUserID (varchar) to the primary key of my table (int). I can’t change the ProviderUserID as there are some systems that use strings as their primary keys (URLs / emails / etc).
This problem can be solved with SQL simply:
SELECT * FROM MyTable AS M
LEFT OUTER JOIN UserAccess AS U ON U.ProviderID = 42 AND M.ID = U.ProviderUserID
But in Entity Framework and more specifically, a combination of LINQ to Entities and SQL Compact Edition – I’m unable to do type casting at runtime.
The obvious candidates like Convert.ToString() and Convert.ToInt() don’t work as it’s L2E. And the SqlFunctions.Convert isn’t available as this is SQL CE.
This problem probably goes away if I go off SQL CE and can use the SqlFunctions, but as CE is quite useful for quickly building a working DbContext for Unit Testing with – I was less excited about doing that – though it’s a possibility if I can’t find a way around this.
I’ve tried a number of ways, and got close with different failings each time. The one below would work great if both types (UserAccess.ProviderUserID and MyTable.ID) were of the same type – but they aren’t 🙂
var data = (from m in DB.MyTable
let userID = DB.UserAccess.Where(x => x.ProviderID == 42).FirstOrDefault(x => p.ID == x.ProviderUserID).UserID
select new DomainModel()
{
ID = m.ID
Email = m.Email,
IsDeleted = m.IsDeleted,
UserID =userID,
});
Any thoughts on where I’m going wrong or what I can do to battle this?
While this is not the ideal solution, it’s the one I’ve settled on for the time being.
I was then able to tweak the query to look similar to the following:
I’ll keep an eye on this question and if there are any better answers I’ll happy upvote / change my accepted answer.
p.s. as an aside, the
.Trim()was added as the initial string conversion was adding buckets full of whitespace to the start of the string.