我使用的是EF Core 6.0,不知道在给定简化示例的情况下,以下内容是否可以将导航公开/配置为不同的类型?如果是,怎么办?
在我的DDD实体中,公开为不同的类型(即ISomeChildInterface
而不是SomeChild
(是可取的,因为我希望ParentClass.Children[0].FirstName
等可以访问(从我的中介处理程序(,但不能访问ParentClass.Children[0].SomeMethod()
,以保护我在ParentClass.CallSomeChildMethod()
中的业务规则/不变量。
还要注意我目前是如何使用.AutoInclude()
和.HasQueryFilter()
的,如果这有区别的话。
当我尝试创建迁移时,我得到了一个错误导航"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
。