比较Where子句中的ComplexType EFCore

问题描述 投票:0回答:1

我有一个名为

MSISDN
的复杂类型,如下所示:

  public class MSISDN 
  {
      public string NDC { get; set; }
      public string CC { get; set; }
      public string SN { get; set; }
      public string ToString() => $"{NDC}{SN}{CC}";
      public string ToLong() => NDC * Math.Power(10, 6) + SN * Math.Power(10,3) + CC;
  }

我还为这个复杂类型编写了一个特定的ValueConverter:

public class MsisdnValueConverter : ValueConverter<Msisdn, string>
{
     public MsisdnValueConverter() : base(msisdn => msisdn.ToString(), msisdnString => Msisdn.Parse(msisdnString), mappingHints: null) { }
}

哪个序列化/反序列化这个复杂类型。我要写以下查询:

SubscriberCard card = cardDbSet.FirstOrDefault(P => P.Msisdn == msisdn);

此代码引发以下异常:

无法将“System.String”类型的对象转换为“System.Int64”类型。

我尝试使用

ToString()
来避免比较对象,只要它们存储为字符串(或更精确的
NVARCHAR(MAX)
) 因此,在我的下一次尝试中,我使用了以下查询:

SubscriberCard card = cardDbSet.FirstOrDefault(P => P.Msisdn.ToString() == msisdn.ToString());

它还会引发以下异常:

无法翻译。附加信息:方法“object.ToString”的翻译失败。如果此方法可以映射到您的自定义函数,请参阅 https://go.microsoft.com/fwlink/?linkid=2132413 了解更多信息。以可翻译的形式重写查询,或者通过插入对“AsEnumerable”、“AsAsyncEnumerable”、“ToList”或“ToListAsync”的调用来显式切换到客户端计算。请参阅 https://go.microsoft.com/fwlink/?linkid=2101038 了解更多信息

对我来说唯一可行的方法是通过调用

ToList()
将所有记录检索到内存中。但要花很多钱。

正如最新的例外所说,我将尝试编写 DbFunction,对我来说还有更好的选择吗?

c# asp.net-web-api entity-framework-core ef-core-8.0
1个回答
0
投票

具有转换的属性不能在 LINQ 查询中使用。

SubscriberCard
属性中定义,该属性保存真实的数据库字符串并将其映射到表的列。还定义属性
Msisdn
,它可以从字符串
填充
MSISDN

对象
public class SubscriberCard
{
    ...
    public string MsisdnString {get; set;}   

    [NotMapped]
    public MSISDN Msisdn { get => Msisdn.Parse(MsisdnString); set => MsisdnString = value.ToString(); }   
}

并在查询中使用

MsisdnString
属性。

SubscriberCard card = cardDbSet.FirstOrDefault(P => P.MsisdnString == msisdn.ToString());
© www.soinside.com 2019 - 2024. All rights reserved.