EF Core 3:配置导航的支持字段 属性

EF Core 3: Configure backing field of navigation property

考虑以下 class。它试图保护对 _assignedTrays.

的访问

实际上,它工作得很好,因为 EF 自动将支持字段 _assignedTrays 链接到 属性 AssignedTrays - 按照惯例 (msdn)

    public class Rack
    {
        private List<Tray> _assignedTrays = new List<Tray>();

        private Rack()
        {
        }

        public Rack(string rackId)
        {
            this.Id = rackId;
        }

        public string Id { get; private set; }

        public IReadOnlyList<Tray> AssignedTrays => this._assignedTrays.AsReadOnly();

        public void Assign(params Tray[] trays)
        {
            this._assignedTrays.AddRange(trays);
        }
    }

问题是,我们的编码风格禁止在变量名中使用下划线 ;-)

根据其他代码示例 (here),应该可以将 _assignedTrays 重命名为 assignedTrays 并明确通知 EF 关于 OnModelCreating 中的更改:

    modelBuilder.Entity<Rack>(e =>
    {
        e.Property(t => t.AssignedTrays).HasField("assignedTrays");
    });

但这给了我以下异常:

System.InvalidOperationException: The property 'Rack.AssignedTrays' is of type 'IReadOnlyList<Tray>' which 
is not supported by current database provider. Either change the property CLR type or ignore the property
using the '[NotMapped]' attribute or by using 'EntityTypeBuilder.Ignore' in 'OnModelCreating'.

我在这里错过了什么?应该不行吗?

文档不反映实际规则,因为 <camel-cased property name>("standard" C# 支持字段命名约定) 绝对受支持,甚至可能具有最高优先级。

但是假设不支持您的命名约定。您仍然可以映射支持字段,但不能使用 Property 流畅 API 来映射,因为根据 EF Core 术语导航属性不是 "properties",而是 "navigations"。这适用于所有流畅、更改跟踪等。APIs.

为了配置导航,您需要访问关系生成器。然后你可以使用关联元数据的 PrincipalToDependentDependentToPrrncipal 属性来 access/configure 关系的两端。

或者直接使用元数据 APIs(目前还没有专门的 fluent API)。

例如:

modelBuilder.Entity<Rack>()
    .FindNavigation(nameof(Rack.AssignedTrays))
    .SetField("assignedTrays");