我收到以下错误,但我不确定如何重写我的声明? 有什么想法吗?
错误:
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();
}
答案 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;
你可以更快地编制索引。