提问人:Caleb H. 提问时间:11/16/2023 最后编辑:Caleb H. 更新时间:11/17/2023 访问量:46
如何比较两个不同子类型的属性?
How can I compare two properties which are different child types?
问:
将 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 查询运行良好,因为 并且都只是字符串。Left
ChildOne
但 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。
ChildOne
BaseType
(BaseType)classOne.ChildOne
join
使用 和 ,但查询仍然抛出它无法创建 SQL 查询。
ChildOne.Raw
BaseType.Raw
join
使用喜欢,这有效!生成的 SQL 略有不同,因为它使用 .但我看不出任何性能差异,甚至执行计划看起来也几乎相同。我想这是一种解决方案,但我宁愿能够使用该方法,因为它更接近代码的意图。
.Where(...Any)
context.ClassOnes.Where(classOne => context.TypePairs.Any(typePair => typePair.Left == classOne.Id))
... where exists (select ...
join
Join
答: 暂无答案
评论