【问题标题】:Configure Fluent API in EF Core for nested Classes在 EF Core 中为嵌套类配置 Fluent API
【发布时间】:2021-10-16 15:31:58
【问题描述】:

我正在使用带有 Asp Net Core 的 EF Core。

我有一个User.cs 课程

public class User
{
   public int Id { get; set; }
   public Contact Contact { get; set; }
}

还有一个Contact.cs

public class Contact
{
   
   public List<PhoneNumber> PhoneNumbers { get; set; }
}

这是我的建造者

 protected override void OnModelCreating(ModelBuilder builder)
        {
            base.OnModelCreating(builder);            
          
            builder.Entity<User>().OwnsOne(x => x.Contact);
         }

所以我的问题是关于“如何设置我的联系人(嵌套在用户中)可能有一个电话号码对象列表”? 我想要的只是所有内容都存储在一张表中,问题不在于每个用户存储多个电话号码。

【问题讨论】:

标签: asp.net-core entity-framework-core


【解决方案1】:

你不需要。您可以简单地继续声明它。正如您在此处看到的,EF Core 是“smart”。它识别出它的导航属性。

只需声明您的课程即可。如果你放入一个列表,它会自动在模式中捕获它并创建它。

您的 FluentAPI 也不需要 OwnsOne,除非您希望尽可能强制执行它,但这取决于数据库。

builder.Entity<Contact>().HasMany(x => x.PhoneNumbers); // does nothing new. Maybe you want for clarity or if you want extra configurations

现在如何为用户检索所有这些?

有了Select就不需要JSON转换了:

users.FirstOrDefault(u =&gt; u.Id = "random_id").Select(u =&gt; u.Contact.PhoneNumbers)

确保您的类具有导航的 ID 属性。例如,您的 Contact.cs 将在数据库中有一个不可见的 UserId 列,但您不会在代码中拥有它。这不是必需的,但它是一个很好的做法。或者更好地在Contact 上添加User 属性。

【讨论】:

    【解决方案2】:

    您可以将序列化为 JSON 的 PhoneNumbers 列表存储在表中。 EF Core 允许您使用 值转换s 无缝地执行此序列化和反序列化。

    使用Microsoft's example 作为参考:

    builder.Entity<User>()
        .Property(e => e.PhoneNumbers)
        .HasConversion(
            v => JsonSerializer.Serialize(v, null),
            v => JsonSerializer.Deserialize<List<PhoneNumber>>(v, null),
            new ValueComparer<ICollection<PhoneNumber>>(
                (c1, c2) => c1.SequenceEqual(c2),
                c => c.Aggregate(0, (a, v) => HashCode.Combine(a, v.GetHashCode())),
                c => (ICollection<PhoneNumber>)c.ToList()));
    

    更多信息

    【讨论】:

      【解决方案3】:

      如果您的 PhoneNumber 对象不存储除电话号码之外的任何其他值,您可以将其存储为多个字符串值,由一个通用分隔符分隔:

      public class Contact
      {   
         public string[] PhoneNumbers { get; set; }
      }
      

      流畅的 API:

      modelBuilder.Entity<Contact>()
                  .Property(e => e.PhoneNumbers)
                  .HasConversion(
                      v => string.Join(';', v),
                      v => v.Split(';', StringSplitOptions.RemoveEmptyEntries));
      

      否则,如果 PhoneNumber 有多个值,我会按照 @abdusco 的回答进行 JSON 序列化/反序列化。

      【讨论】:

        猜你喜欢
        • 2018-08-18
        • 2018-08-16
        • 1970-01-01
        • 1970-01-01
        • 2018-02-07
        • 1970-01-01
        • 2021-04-27
        • 2023-01-19
        • 1970-01-01
        相关资源
        最近更新 更多