Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/330.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 将POCO映射到Linq到Sql中的字符串,以便在POCO上使用Linq_C#_Linq_Linq To Sql - Fatal编程技术网

C# 将POCO映射到Linq到Sql中的字符串,以便在POCO上使用Linq

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

我正在访问一个数据库列,其中电话号码以+a-b:c格式存储为varchar,其中a=国家代码,b=电话号码,c=分机号码。例如+44-07700123456:123

因此,我有一个处理序列化的类型:

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设置为私有,并通过构造函数进行设置。