【问题标题】:How to configure Owned type referencing another entity in ef core 6如何在 ef core 6 中配置引用另一个实体的拥有类型
【发布时间】:2022-01-25 12:47:05
【问题描述】:

我有一个名为 Slot 的实体。

public class Slot : Entity
{
    public virtual SnackPile SnackPile { get; set; }
}

这里的SnackPile 是一个ValueObject,没有自己的表。它归插槽所有。 SnackPile 看起来像这样。

public sealed class SnackPile : ValueObject<SnackPile>
{
    public static readonly SnackPile Empty = new SnackPile(Snack.None, 0, 0m);
    public Snack Snack { get; } // Please note this Snack, we will come to this.
    public int Quantity { get; }
    public decimal Price { get; }
    private SnackPile() { }
}

所以要配置它,我有以下内容。

modelBuilder.Entity<Slot>().OwnsOne(slot => slot.SnackPile, slotToSnackpile =>
{
    slotToSnackpile.Property(ss => ss.Price).IsRequired();
    slotToSnackpile.Property(ss => ss.Quantity).IsRequired();
    //slotToSnackpile.Navigation(p => p.Snack).IsRequired(); // This is not working.
}).Navigation(slot => slot.SnackPile).IsRequired();

到目前为止一切顺利。

现在 SnackPile 具有 Snack 属性,这是一个实体。如何配置这个? 如您所见,我尝试添加此

slotToSnackpile.Navigation(p => p.Snack).IsRequired(); // This is not working.

它给出了以下错误。

Navigation 'SnackPile.Snack' was not found. Please add the navigation to the entity type before configuring it.

也尝试了以下两个,但没有成功。

//slotToSnackpile.Property(ss => ss.Snack).IsRequired();

这会产生以下错误。 The property 'SnackPile.Snack' is of type 'Snack' which is not supported by the current database provider. Either change the property CLR type, or ignore the property using the '[NotMapped]' attribute or by using 'EntityTypeBuilder.Ignore' in 'OnModelCreating'.

还有这个

//slotToSnackpile.Property(ss => ss.Snack.Id).IsRequired();

我得到了错误。 The expression 'ss =&gt; ss.Snack.Id' is not a valid member access expression. The expression should represent a simple property or field access: 't =&gt; t.MyProperty'. (Parameter 'memberAccessExpression')

卡住了:(有什么想法吗?

【问题讨论】:

标签: c# ef-core-6.0


【解决方案1】:

默认情况下,EF Core 仅映射具有公共 getter 和任何 setter(可以是私有的、受保护的等)的属性(原始或类似导航)。

由于您的所有属性(包括有问题的属性)都是仅获取(没有设置器),因此您必须明确映射它们。

对于原始属性,您使用Property fluent API。但是对于导航属性,您需要关系流式 API,例如Has / With 对。在你的情况下:

slotToSnackpile.HasOne(e => e.Snack).WithMany().IsRequired();

【讨论】:

  • 感谢伊万,它的工作。有什么方法可以配置结果列的名称?试过 slotToSnackpile.HasOne(e => e.Snack).WithMany().HasColumnName("Snack");最后添加了 HasColumnName,但这没有编译。
  • @VivekDev 使用此 API,您可以配置影子 FK 属性名称,例如.HasForeignKey("SnackId")。然后您可以像往常一样使用.HasColumnName 配置其列名,例如slotToSnackpile.Property("SnackId").HasColumnName("Snack");
  • 需要更多地了解shadow FK。谢谢 无论如何,我会调查一下。
猜你喜欢
  • 2021-01-27
  • 1970-01-01
  • 1970-01-01
  • 2018-06-04
  • 2010-12-05
  • 1970-01-01
  • 2021-04-28
  • 1970-01-01
  • 2022-08-17
相关资源
最近更新 更多