如何比较两个不同子类型的属性?

How can I compare two properties which are different child types?

提问人:Caleb H. 提问时间:11/16/2023 最后编辑:Caleb H. 更新时间:11/17/2023 访问量:46

问:

将 Entity Framework 与 SQL Server 配合使用时,我具有如下所示的类型:

public abstract record BaseType(string Raw);
public record ChildOne(string Raw) : BaseType(Raw);
public record ChildTwo(string Raw) : BaseType(Raw);

public class ClassOne {
    public ChildOne ChildOne {get; set;}
}

public class ClassTwo {
    public ChildTwo ChildTwo {get; set;}
}

public class BaseTypePair {
    public BaseType Left {get; set;}
    public BaseType Right {get; set;}
}

// Converters
public class BaseTypeConverter : ValueConverter<BaseType, string> {...}
public class ChildOneConverter : ValueConverter<ChildOne, string> {...}
public class ChildTwoConverter : ValueConverter<ChildTwo, string> {...}

在数据库上下文中,我有 、 和 属性。DbSet<ClassOne>DbSet<ClassTwo>DbSet<BaseTypePair>

现在我想像这样加入他们:

context
    .BaseTypePairs
    .Join(context.ClassOnes,
          baseTypePair => baseTypePair.Left,
          classOne => classOne.ChildOne,
          (baseTypePair, classOne) => classOne)
    .ToList() // Something to actually run the Queryable

应该转换为类似的东西

select ClassOne.*
from BaseTypePairs
join ClassOne on BaseTypePairs.Left = ClassOne.ChildOne

并且该 SQL 查询运行良好,因为 并且都只是字符串。LeftChildOne

但 LINQ 总是发出警告,然后引发异常。

警告:。这是有道理的,除非你要在 C#(内存中)进行联接,否则它会正常工作。Possible unintended use of method 'Equals' for arguments 'baseTypePair.Left' and 'classOne.classOne.ChildOne' of different types in a query. This comparison will always return false.

例外:System.InvalidOperationException: Unhandled expression '[Microsoft.EntityFrameworkCore.Query.SqlExpressions.SqlConstantExpression]' of type 'Microsoft.EntityFrameworkCore.Query.SqlExpressions.SqlConstantExpression' encountered in 'SqlNullabilityProcessor'.

还尝试过

  • 转换为 like ,但随后查询会引发异常,指出它无法将 LINQ 查询转换为 SQL。ChildOneBaseType(BaseType)classOne.ChildOnejoin

  • 使用 和 ,但查询仍然抛出它无法创建 SQL 查询。ChildOne.RawBaseType.Rawjoin

  • 使用喜欢,这有效!生成的 SQL 略有不同,因为它使用 .但我看不出任何性能差异,甚至执行计划看起来也几乎相同。我想这是一种解决方案,但我宁愿能够使用该方法,因为它更接近代码的意图。.Where(...Any)context.ClassOnes.Where(classOne => context.TypePairs.Any(typePair => typePair.Left == classOne.Id))... where exists (select ...joinJoin

C# 实体框架

评论


答: 暂无答案