实体框架 - 字符串转换错误

时间:2016-08-09 11:11:02

标签: c# entity-framework

我收到以下错误,但我不确定如何重写我的声明? 有什么想法吗?

错误:

  

LINQ to Entities无法识别方法'System.String   转换(System.String)'方法,此方法无法翻译   进入商店表达

代码:

public Client FindClientByMobile(string mobile, string accountId)
{
    Client client = RepositorySet.Include("Account").FirstOrDefault(c => c.AccountId == accountId && !c.IsDeleted
            && ((Convert(c.TelephoneHome) == mobile) || (Convert(c.TelephoneMobile) == mobile) || (Convert(c.TelephoneWork) == mobile)));
    return client;
}

public static string Convert(string mobile)
{
    var filterNumber = from letter in mobile
                       where char.IsDigit(letter)
                       select letter;

    StringBuilder number = new StringBuilder();
    number.Append(filterNumber.ToArray());

    return number.ToString();
}

3 个答案:

答案 0 :(得分:4)

错误意味着Linq需要将表达式转换为Sql语句。您的自定义Convert方法不可翻译,因为它是c#代码,而不是数据库服务器上也存在的东西。

由于您已经传入了您的帐户ID,我将假设它是唯一的或者将其过滤到足以接近唯一的位置,以确保您不会检索大量对象。然后,您可以首先实现对象图,然后在c#(linq到对象)中过滤更多。这是通过ToList()调用完成的。

public Client FindClientByMobile(string mobile, string accountId)
{
  var clients = RepositorySet.Include("Account").Where(c => c.AccountId == accountId && !c.IsDeleted).ToList();
  return clients.FirstOrDefault(client => Convert(client.TelephoneHome) == mobile || Convert(client.TelephoneMobile) == mobile || Convert(client.TelephoneWork) == mobile);
}

答案 1 :(得分:1)

这是否适合您,正如您在评论中提到的那样

   @Imad,我试图做的是验证,所以如果数字已经存在   存储在数据库中为0331-9000-100,我想删除所有非   数字字符,移动已经应用了这个,所以mobile =   033319000100

Replace

使用(您还可以替换)Replace(char, char)等其他字符。

要记住:Replace(string, string)不会工作,但float80会。

答案 2 :(得分:0)

第一个问题是转换调用是C#,无法转换为SQL。并非所有函数都可以,但有些(例如子字符串)是已知的'到实体框架,它可以将它们转换为适当的SQL。因此,您需要重写语句以使用EF所知的字符串函数,或者以其他方式将逻辑推送到数据库中。

@Imad已经建议使用string.Replace,其中 已为EF所知,但当然它不会帮助您删除所有可能的非数字字符 - 仅您明确编码的内容,例如' - ',而不是其他字母字符串,例如' extension'。

如果你想快速做到这一点,最好存储“清理过的”。单独字段中的数字。然后查询变为

Client client = RepositorySet.Include("Account").FirstOrDefault(c => c.AccountId == accountId && !c.IsDeleted
        && (c.TelephoneHomeClean == mobile) || (c.TelephoneMobileClean == mobile) || (c.TelephoneWorkClean == mobile)));
return client;

你可以更快地编制索引。