如何使用 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 这种情况下进行映射。
- C# 模型:
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;
}
}
- SQL结构
- 请求是一个 table,在 EfCore 中映射到实体请求
- DiaryEntries 是一个 table,它存在于 EfCore 中,并间接映射到一个 DbSet,Request 为 "HasOne",因此它具有关系。
- table'Diary'不存在,是一个封装逻辑的'complex type',所以不用在'Request'类型中处理在 C#
我不相信 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 中支持的行为负责。
我想在 Ef Core 中映射一个复杂类型(换句话说,一种不直接映射到 table 的类型),它包含一个直接映射到 [=] 的对象列表52=].
考虑下面的例子,你会发现日记逻辑(我现在只显示 AddEntry)是分开的来自请求 class,因为它不在乎。
我在 Ef Core 中使用 .OwnsOne 没有任何问题,当使用更简单的类型时,数据存储在相同的 table 中(例如:这里它会在请求 table);但我不知道或不知道如何在 OnConfiguring 这种情况下进行映射。
- C# 模型:
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;
}
}
- SQL结构
- 请求是一个 table,在 EfCore 中映射到实体请求
- DiaryEntries 是一个 table,它存在于 EfCore 中,并间接映射到一个 DbSet,Request 为 "HasOne",因此它具有关系。
- table'Diary'不存在,是一个封装逻辑的'complex type',所以不用在'Request'类型中处理在 C#
我不相信 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 中支持的行为负责。