如何使用 Ef Core 将集合封装到 "complex type" 对象中(包括示例)

How do I encapsulate a collection into a "complex type" object with Ef Core (example included)

我想在 Ef Core 中映射一个复杂类型(换句话说,一种不直接映射到 table 的类型),它包含一个直接映射到 [=] 的对象列表52=].

考虑下面的例子,你会发现日记逻辑(我现在只显示 AddEntry)是分开的来自请求 class,因为它不在乎。

我在 Ef Core 中使用 .OwnsOne 没有任何问题,当使用更简单的类型时,数据存储在相同的 table 中(例如:这里它会在请求 table);但我不知道或不知道如何在 OnConfiguring 这种情况下进行映射。

public class Request : DbEntity {
   public Diary { get; set; }
}

public class DiaryEntry : DbEntity {
   public DateTimeOffset Timestamp { get; set; }
   public Request Request { get; set; }
   public string Message { get; set; }   
}

public class Diary {
   private readonly List<DiaryEntry> _entries = new List<DiaryEntry>();
   public Request Request { get; set; }
   public IEnumerable<DiaryEntry> Entries => _entries;
   public Diary AddEntry(DiaryEntry diaryEntry) {
      if(diaryEntry != null)
         _entries.Add(diaryEntry);
      return this;
   }
}

我不相信 Entity Framework 支持这样的任何东西,因为复杂类型旨在支持将一个 table 上的属性组织成相关的 classes 而没有关系 table秒。在您的情况下,您希望采用关系 tables 并映射一个中间 class 以避免在父 class.

中制定有关管理子集合的规则

我可以提出一个选项来帮助解决您似乎希望在 class 之间具有的关注点分离,即利用扩展方法来实现您希望为日记公开的特定于集合的逻辑。

例如:

[Table("Requests")]
public class Request
{
    [Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int RequestId { get; set; }
    public string Name { get; set; }

    public virtual IEnumerable<DiaryEntry> Diary { get; protected set; } = new List<DiaryEntry>();
}

[Table("DiaryEntries")]
public class DiaryEntry
{
    [Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int DiaryEntryId { get; set; }
    public string Value { get; set; }

    public virtual Request Request { get; set; }
}

在这里,我们将日记公开为 IEnumerable<DiaryEntry>,这样实体的消费者就无法修改集合等。从那里,日记功能可以通过扩展来管理:

public static class DiaryExtensions
{
    public static DiaryEntry AddEntry(this IEnumerable<DiaryEntry> diary, DiaryEntry newEntry)
    {
        ICollection<DiaryEntry> diaryList = (ICollection<DiaryEntry>)diary;
        if (newEntry != null)
            diaryList.Add(newEntry);

        return newEntry;
    }
}

就我个人而言,我会在请求中使用此逻辑,因为日记条目与请求相关联。为了分离日记特定的逻辑,我将使用部分 classes,但对包含它们的 class 中支持的行为负责。