如何使用 EF 7 编写高效的值比较器

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

我有以下对象:

public record Attachment
{
    public required string DocumentId { get; set; }
    public required DocumentType DocumentType { get; set; }
    public required string MimeType { get; set; }
    public string? Notes { get; set; }
}

我为 ScreenShot 属性编写了这个转换器,该属性是 Attachment 类型:

  builder.Property(x => x.ScreenShot)
        .HasConversion(
        x => JsonSerializer.Serialize(x, JsonSerializerOptions.Default),
        x => JsonSerializer.Deserialize<Attachment>(x, JsonSerializerOptions.Default)!,
        new ValueComparer<Attachment>(
                 (c1, c2) => JsonSerializer.Serialize(c1, JsonSerializerOptions.Default) == JsonSerializer.Serialize(c2, JsonSerializerOptions.Default),
                 c => JsonSerializer.Serialize(c, JsonSerializerOptions.Default).GetHashCode(),
                 c => JsonSerializer.Deserialize<Attachment>(JsonSerializer.Serialize(c, JsonSerializerOptions.Default), JsonSerializerOptions.Default)!));

上述转换器正确且高性能吗?如何在不需要序列化逻辑的情况下以另一种更高性能的方式编写它?

c# entity-framework
1个回答
0
投票

如果

DocumentType
是正确实现
Equals
GetHashcode
的类型,因为
Attachment
实际上是
record
,您可以利用生成的相等性并为其复制成员:

.HasConversion(
    x => JsonSerializer.Serialize(x, JsonSerializerOptions.Default),
    x => JsonSerializer.Deserialize<Attachment>(x, JsonSerializerOptions.Default)!,
    new ValueComparer<Attachment>(
        (c1, c2) => c1 == c2,
        c => c.GetHashCode(),
        c => c.CloneForExpression())
);
public record Attachment
{
    // needed because with can't be used in expressions ATM
    public Attachment CloneForExpression() => this with { };

    // ...
}

这应该比来回序列化数据更有效(尽管理论上它更脆弱,甚至是直接错误,具体取决于由于浅复制而导致的

DocumentType
实际上是什么类型,请参阅记录文档的非破坏性突变部分) )。如果这里的浅复制是错误的,那么你需要更新

© www.soinside.com 2019 - 2024. All rights reserved.