找不到属性的支持字段,并且该属性没有带有值对象的 getter

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

我有客户课程:

public class Client
{
    public int Id { get; set; }
    public ClientId ClientId { get; set; }
}

和值对象(记录)

ClientId
:

public record ClientId
{
    private ClientId() { }

    public ClientId(string clientId)
    {
        if (!CanCreate(clientId))
            throw new ArgumentException($"'{nameof(clientId)}' must be 32 bytes long Base64Url encoded string.");

        Value = clientId;
    }

    public string Value { get; private init; }

    public static bool CanCreate(string clientId)
    {
        return !string.IsNullOrEmpty(clientId) && Base64UrlEncoder.Validate(clientId, out int length) && length == 32;
    }
}

当我想通过

Client
找到
ClientId
时:

public async Task<T?> FindByClientId<T>(ClientId clientId, Expression<Func<Client, T>> selector, CancellationToken cancellationToken = default,
    params Expression<Func<Client, object>>[] include)
{
    if (selector is null) throw new ArgumentNullException(nameof(selector));

    var baseQuery = _dbContext.Clients.AsNoTrackingWithIdentityResolution()
        .Where(p => p.ClientId == clientId);
    
    return await include.Aggregate(baseQuery, (current, inc) => current.Include(inc))
        .Select(selector)
        .SingleOrDefaultAsync(cancellationToken);
}

我总是收到此错误:

System.InvalidOperationException: No backing field could be found for property 'ClientId.ClientId' and the property does not have a getter.

这是我的

Client
配置:

public class ClientConfiguration : IEntityTypeConfiguration<Client>
{
    public void Configure(EntityTypeBuilder<Client> builder)
    {
        builder.OwnsOne(p => p.ClientId, buildAction =>
        {
            buildAction.Property(p => p.Value)
            .HasColumnName(nameof(Client.ClientId))
            .HasMaxLength(43);

            buildAction.HasIndex(p => p.Value).IsUnique();
        });
    }
}

为什么这不起作用?我做错了什么?

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

我遇到了同样的问题,并且该问题似乎仅在对值对象使用唯一约束时才会发生:

buildAction.HasIndex(p => p.Value).IsUnique()

解决方案涉及将与

ClientId
类中的
Id
字段(在您的情况下为
Client
)具有相同类型的
int
字段添加到
ClientId
值对象。尽管在您的特定场景中包含此字段可能看起来很尴尬,但 EF Core 将其用作将 ClientId 值对象链接回客户端实体的外键。无论字段是否存储为同一个表中的列,都会发生这种链接。

public record ClientId
{
    public int ClientId { get; private set; }
    // rest of the code...
}

添加属性后,一切都应该运行良好,无需创建迁移。请注意,添加的属性应该有一个 setter,无论是公共的还是私有的。

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