在 EF Core 6.0 中将导航公开为不同类型

Exposing a Navigation as a different type in EF Core 6.0

我正在使用 EF Core 6.0,我想知道,给出简化的示例,以下内容是否可以 expose/configure 导航作为不同类型?如果是的话怎么办?

在我的 DDD 实体中希望公开为不同的类型(即 ISomeChildInterface 而不是 SomeChild),因为我希望 ParentClass.Children[0].FirstName 等可以访问(从我的中介处理程序)但不是 ParentClass.Children[0].SomeMethod() 为了在 ParentClass.CallSomeChildMethod().

中保护我的 businessrules/invariants

另请注意我目前是如何使用 .AutoInclude().HasQueryFilter() 的,如果这会有所不同的话。

当我尝试创建迁移时,出现 Navigation 'SomeParent.Children' 未找到的错误。请在配置之前将导航添加到实体类型中。

    public interface ISomeChildInterface
    {
        Guid Id { get; }
        string FirstName { get; }
        string LastName { get; }
    }

    public class SomeChildClass : ISomeChildInterface
    {
        public Guid Id { get; private set; }

        public string FirstName { get; private set; } = null!;

        public string LastName { get; private set; } = null!;

        //parameterless constructor required by EF Core
        private SomeChildClass()
        {

        }

        //private constructor
        private SomeChildClass(string firstName, string lastName)
        {
            Id = Guid.NewGuid();
            FirstName = firstName;
            LastName = lastName;
        }

        //Static factory create method
        public static SomeChildClass Create(string firstName, string lastName)
        {
            return new SomeChildClass(firstName, lastName);
        }

        public void SomeMethod()
        {

        }
    }

    public class ParentClass
    {
        private readonly List<SomeChildClass> _children = new();

        public IReadOnlyCollection<ISomeChildInterface> Children => _children.AsReadOnly();

        public void AddChild(SomeChildClass someChild)
        {
           _children.Add(someChild);
        }

        public void CallSomeChildMethod(Guid childId)
        {
           // Some business rules etc 
           _children.SingleOrDefault(x => x.id => childId).SomeMethod();
        }
    }

    public class SomeContext : IdentityContext
    {
        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            base.OnModelCreating(modelBuilder);

            // ... snip ...
            _ = modelBuilder.Entity<ParentClass>(entity =>
            {
               _ = entity.Navigation(x => x.Children).AutoInclude().HasField("_children").UsePropertyAccessMode(PropertyAccessMode.Field);

              //_ = entity.HasQueryFilter(e => UserRoles.Any(x => x.UserId == CurrentUserId && x.RoleId == e.RoleId));
            }
        }
    }

不,ParentClass.Children 不能是导航 属性,但您可以将导航 属性 设为私有。例如

builder.Entity<ParentClass>().HasMany("_children").WithOne();

但是您将无法在翻译成 SQL 的查询中使用 ParentClass.Children