在EF4.1&中加入Int to String SQLCE

时间:2011-12-29 10:14:01

标签: c# linq entity-framework casting sql-server-ce

我有两个数据库表:

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

MyTable的

ID              int    
IsDeleted       bit    
Email           varchar(255)   

UserAccess

UserID          guid    
ProviderID      int    
ProviderUserID  varchar(255)   

这两个表都是通过实体框架4.1代码优先在我的应用程序中设置的。

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

当我试图通过将ProviderUserID(varchar)映射到我的表(int)的主键来找出MyTable中的特定记录属于谁时,我的问题出现了。我无法更改ProviderUserID,因为有些系统使用字符串作为主键(URL /电子邮件/等)。

这个问题可以通过SQL简单解决:

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

但是在Entity Framework中,更具体地说,是LINQ to Entities和 SQL Compact Edition 的组合 - 我无法在运行时进行类型转换。

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

有关我出错的地方或我可以做些什么来解决这个问题的想法?

1 个答案:

答案 0 :(得分:0)

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

  • 我已将单元测试使用的数据库更改为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,
            });

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

P.S。另外,.Trim()被添加,因为初始字符串转换是在字符串的开头添加满空格的桶。