Joining on Int to String in EF4.1 & SQLCE

本文关键字:amp SQLCE EF4 in on Int to String Joining | 更新日期: 2023-09-27 18:19:04

我有两个数据库表:

  • 'MyTable'有一个标准的自动递增的主键整数字段。
  • 'UserAccess'表是一个映射表,包含通过复合键连接到所有系统的链接。

MyTable :

ID              int    
IsDeleted       bit    
Email           varchar(255)   

UserAccess :

UserID          guid    
ProviderID      int    
ProviderUserID  varchar(255)   

两个表都是通过Entity Framework 4.1 Code First在我的应用程序中设置的。

主表(我的系统/提供者)有它自己的ID(例如42)。它可以通过查找表中是否有42的ProviderID的记录来查找用户是否具有访问权限。

我的问题来了,当试图找出谁在MyTable中的特定记录属于通过映射ProviderUserID (varchar)到我的表(int)的主键。我不能改变ProviderUserID,因为有一些系统使用字符串作为他们的主键(url/电子邮件/等)。

这个问题可以用SQL简单地解决:

SELECT * FROM MyTable AS M
LEFT OUTER JOIN UserAccess AS U ON U.ProviderID = 42 AND M.ID = U.ProviderUserID

但是在实体框架中,更具体地说,LINQ to Entities和SQL精简版的组合-我无法在运行时进行类型转换。

明显的候选物如Convert.ToString()Convert.ToInt()不工作,因为它是L2E。SqlFunctions.Convert是不可用的,因为这是SQL CE。

这个问题可能会消失,如果我离开SQL CE,可以使用SqlFunctions,但CE是非常有用的快速构建一个工作DbContext与单元测试-我不太兴奋这样做-虽然这是一种可能性,如果我找不到一个方法围绕这个。

我尝试了很多方法,每次都以不同的失败告终。如果两种类型(UserAccess.ProviderUserIDMyTable.ID)是相同的类型,下面的一个将会工作得很好-但它们不是:)

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,
            });

有什么想法,我在哪里做错了,或者我能做些什么来对抗这个?

Joining on Int to String in EF4.1 & SQLCE

虽然这不是理想的解决方案,但这是我暂时选定的解决方案。

  • 我已经将单元测试使用的数据库改为SQL Express数据库,这使我能够使用SqlFunctions类和其中的方法。

然后我可以调整查询,使其看起来类似于以下内容:

var data = (from m in DB.MyTable
            join i in DB.UserAccess.Where(x => x.ProviderID == 42) on SqlFunctions.StringConvert((double)m.ID).Trim() equals i.ProviderUserID into useraccess
            from ua in useraccess.DefaultIfEmpty()
            select new DomainModel()
            {
               ID = m.ID
               Email = m.Email,
               IsDeleted = m.IsDeleted,
               UserID = ua.UserID,
            });

我会密切关注这个问题,如果有更好的答案,我会很高兴投票/改变我接受的答案。

注。顺便说一句,.Trim()是在初始字符串转换将充满空格的桶添加到字符串开头时添加的。