gpt4 book ai didi

entity-framework - 什么是自有实体?何时以及为何在 Entity Framework Core 中使用拥有的实体?

转载 作者:行者123 更新时间:2023-12-03 18:32:10 26 4
gpt4 key购买 nike

我正在学习 Entity Framework Core 。我在几乎所有教程中都遇到了 Owned Entity

这是在 Owned Entity 中使用 Entity Framework Core 的一个示例

作业实体:

public class Job : Entity
{
public HiringManagerName HiringManagerName { get; private set; }
}

HiringManagerName 值对象:

public class HiringManagerName : ValueObject
{
public string First { get; }
public string Last { get; }

protected HiringManagerName()
{
}

private HiringManagerName(string first, string last)
: this()
{
First = first;
Last = last;
}

public static Result<HiringManagerName> Create(string firstName, string lastName)
{
if (string.IsNullOrWhiteSpace(firstName))
return Result.Failure<HiringManagerName>("First name should not be empty");
if (string.IsNullOrWhiteSpace(lastName))
return Result.Failure<HiringManagerName>("Last name should not be empty");

firstName = firstName.Trim();
lastName = lastName.Trim();

if (firstName.Length > 200)
return Result.Failure<HiringManagerName>("First name is too long");
if (lastName.Length > 200)
return Result.Failure<HiringManagerName>("Last name is too long");

return Result.Success(new HiringManagerName(firstName, lastName));
}

protected override IEnumerable<object> GetEqualityComponents()
{
yield return First;
yield return Last;
}
}

实体配置:

public class JobConfiguration : IEntityTypeConfiguration<Job>
{
public void Configure(EntityTypeBuilder<Job> builder)
{
builder.OwnsOne(p => p.HiringManagerName, p =>
{
p.Property(pp => pp.First)
.IsRequired()
.HasColumnName("HiringManagerFirstName")
.HasMaxLength(200);
p.Property(pp => pp.Last)
.IsRequired()
.HasColumnName("HiringManagerLastName")
.HasMaxLength(200);
});
}
}

这在表中创建为两列,就像 Job Entity 中的其他列一样。

enter image description here

由于这也像实体中的其他属性一样被创建为列,因此可以直接添加为 Job Entity 中的普通属性。为什么需要将其添加为 Owned Entity

请任何人都可以帮助我理解,
  • 什么是拥有实体?
  • 为什么我们需要使用拥有的实体?
  • 何时使用自有实体?
  • 最佳答案

    如果没有拥有的实体,这会是什么样子?

    如果您在 EF Core 中创建一个实体 Job ,该实体指向一个复杂对象 HiringManagerName ,在其中一个属性中,EF Core 将期望每个实体都驻留在单独的表中,并期望您定义它们之间的某种关系(例如,一对一、一对多等)。

    检索 Job 时,如果您还想显式加载 HiringManagerName 的值,则必须在查询中使用显式 Include 语句,否则将不会填充。

    var a = dbContext.Jobs
    .Include(b => b.HiringManagerName) //Necessary to populate
    .ToListAsync();

    但是因为每个都被认为是一个单独的实体,所以它们需要公开键,并且您必须在每个实体之间配置外键。

    什么是自有实体?

    这就是 [Owned] 类型的用武之地(参见 docs )。通过使用 [Owned] 属性标记子类,您可以将该关系的显式处理留给 EF Core 进行管理,并且不再需要在拥有的类型上定义键/外键。如果您指向您拥有的类型的集合,则相同 - 您不再需要处理任一类上的导航属性来描述关系。

    EF Core 还支持对这些拥有的类型进行查询,如下所示:
    var job = context.Jobs.Where(a => a.HiringManagerName.First == "fingers10").FirstOrDefaultAsync();

    现在,它带有文档中描述的两个重要的 design restrictions (但在此处详细说明):
  • 不能为拥有的类型
  • 创建 DbSet

    这意味着您不能随后使用以下方式进行数据库调用:
    dbContext.HiringManagerNames.ToListAsync();

    这将抛出,因为您需要简单地检索值作为调用的一部分:
    dbContext.Jobs.ToListAsync();

    与我给出的第一个示例不同, HiringManagerNames 不再需要显式包含,而是通过调用 Jobs DbSet<T> 返回。
  • 无法在 Entity<T>
  • 上使用拥有的类型调用 ModelBuilder
    同样,您不能在模型构建器中引用您拥有的类型来配置它。相反,如果您必须配置它,请通过针对您的 Jobs 实体和拥有的属性(property)进行配置,例如:
    modelBuilder.Entity<Job>().OwnsOne(a => a.HiringManagerNames).//Remaining configuration

    那么我什么时候应该使用拥有的实体?

    如果您的类型只会作为另一种类型的导航属性出现(例如,您永远不会将它本身作为查询的根实体进行查询),请使用拥有的类型以节省一些关系样板.

    如果您曾预期查询独立于父实体的子实体,请不要让它拥有它 - 它需要使用自己的 DbSet<T> 定义以便从上下文中调用。

    关于entity-framework - 什么是自有实体?何时以及为何在 Entity Framework Core 中使用拥有的实体?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61706738/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com