我正在访问一个数据库列,其中电话号码存储为varchar,格式为+ a-b:c,其中a =国家/地区代码,b =电话号码,c =扩展名。例如。 + 44-07700123456:123
所以我有一个处理序列化的类型:
public struct PhoneNumber {
public PhoneNumber(string val) { /*...*/ }
public override string ToString() { /*...*/ }
public static PhoneNumber TryParse(string val) { /*...*/ }
}
和POCO:
public class Customer {
public PhoneNumber? HomePhone;
}
然后在我的数据访问代码中使用了一些Linq:
public IQueryable<Customers> GetCustomers() {
var customers = (from c in DataContext.Customers
select new Customer {
HomePhone = PhoneNumber.TryParse(c.HomePhone)
});
return customers;
}
到目前为止一切顺利,从数据库中检索记录时一切正常,但我的问题是我无法对结果执行Linq查询,如:
GetCustomers().Where(c => c != null && c.HomePhone.Value.ToString().Contains("123"));
我收到错误“Method'System.Nullable`1 [PhoneNumber] TryParse(System.String)'没有支持的SQL转换”。现在我知道我可以在GetCustomers()中执行电话号码搜索,但这并不理想。
有没有办法让Linq知道如何将我的linq翻译成sql?所以我可以做一些像GetCustomers()。其中(c =&gt; c.HomePhone.Value.ToString()。包含(“123”))?
P.S。不确定这个标题,欢迎任何替代方案。
答案 0 :(得分:0)
问题是你的PhoneNumber.TryParse()
调用被转换成一个发送到服务器的表达式,它不理解。此外,没有办法告诉SQL您的结构,因此您将无法根据解析的值执行服务器端查询。一种选择是捕获字符串值并将PhoneNumber.TryParse()
位移到其他位置。例如:
public class Customer {
public string HomePhoneString;
private bool _HomePhoneParsed;
private PhoneNumber? _HomePhone;
public PhoneNumber? HomePhone
{
get
{
if(!_HomePhoneParsed)
{
_HomePhone = PhoneNumber.TryParse(HomePhoneString);
_HomePhoneParsed = true;
}
return _HomePhone;
}
}
}
public IQueryable<Customers> GetCustomers() {
var customers = (from c in DataContext.Customers
select new Customer {
HomePhoneString = c.HomePhone
});
return customers;
}
然后你可以查询服务器端:
GetCustomers().Where(c => c.HomePhoneString != null && c.HomePhoneString.Contains("123"))
或客户端:
GetCustomers().AsEnumerable()
.Where(c => c.HomePhone != null && c.HomePhone.Value.Contains("123"))
答案 1 :(得分:0)
对此进行跟进,另一种解决方案是将PhoneNumber更改为类并添加“Value”属性以序列化/反序列化,如:
public class PhoneNumber {
public override string ToString() { /*...*/ }
public Parse(string val) { /*...*/ }
public string Value {
get {
return ToString();
}
set {
Parse(value);
}
}
}
这种代码并不适合属性,但它允许您在Linq查询中初始化HomePhone对象,如:
var customers = (from c in DataContext.Customers
select new Customer {
FirstName = c.FirstName,
HomePhone = new PhoneNumber {
Value = c.HomePhone
}
});
这意味着您可以使用序列化程序,如:
customers.Where(x => x.HomePhone.Value.Contains("123"));