C# 将POCO映射到Linq到Sql中的字符串,以便在POCO上使用Linq
我正在访问一个数据库列,其中电话号码以+a-b:c格式存储为varchar,其中a=国家代码,b=电话号码,c=分机号码。例如+44-07700123456:123 因此,我有一个处理序列化的类型:C# 将POCO映射到Linq到Sql中的字符串,以便在POCO上使用Linq,c#,linq,linq-to-sql,C#,Linq,Linq To Sql,我正在访问一个数据库列,其中电话号码以+a-b:c格式存储为varchar,其中a=国家代码,b=电话号码,c=分机号码。例如+44-07700123456:123 因此,我有一个处理序列化的类型: public struct PhoneNumber { public PhoneNumber(string val) { /*...*/ } public override string ToString() { /*...*/ } public static PhoneNumber
public struct PhoneNumber {
public PhoneNumber(string val) { /*...*/ }
public override string ToString() { /*...*/ }
public static PhoneNumber TryParse(string val) { /*...*/ }
}
public IQueryable<Customers> GetCustomers() {
var customers = (from c in DataContext.Customers
select new Customer {
HomePhone = PhoneNumber.TryParse(c.HomePhone)
});
return customers;
}
和POCO:
public class Customer {
public PhoneNumber? HomePhone;
}
然后在我的数据访问代码中,一些Linq如下所示:
public struct PhoneNumber {
public PhoneNumber(string val) { /*...*/ }
public override string ToString() { /*...*/ }
public static PhoneNumber TryParse(string val) { /*...*/ }
}
public IQueryable<Customers> GetCustomers() {
var customers = (from c in DataContext.Customers
select new Customer {
HomePhone = PhoneNumber.TryParse(c.HomePhone)
});
return customers;
}
我得到一个错误方法'System.Nullable'1[PhoneNumber]TryParseSystem.String'不支持转换为SQL。现在我知道我可以在GetCustomers中执行电话号码搜索,但这并不理想
有没有办法让Linq知道如何将我的Linq转换为sql?所以我可以做一些像GetCustomers.Wherec=>c.HomePhone.Value.ToString.Contains123这样的事情
另外,我不确定这封信的标题,欢迎您提供其他选择。问题是您的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().AsEnumerable()
.Where(c => c.HomePhone != null && c.HomePhone.Value.Contains("123"))
接下来,另一种解决方案是将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"));
这不是一个理想的解决方案,因为它公开了两个公共“属性”HomePhone和HomePhoneString,但它可以工作并回答问题。谢谢。您还可以将HomePhoneString设置为私有,并通过构造函数进行设置。