【问题标题】:ShadowProperties being reached by foreach before being created在创建之前由 foreach 访问 ShadowProperties
【发布时间】:2018-10-19 08:48:13
【问题描述】:

我是 Entity Framework 的新手,我正在通过 Julie Lerman 的 Pluralsight 课程学习 atm。我正在观看第二门课程“Entity Framework Core 2: Mappings”,但我使用的是 EF Core 2.1。

编辑: 因此,我决定将所有内容注释掉并再次按照课程进行操作,现在它正在工作,但是生成的迁移生成了不应该存在的 2 列:

protected override void Up(MigrationBuilder migrationBuilder)
{
    migrationBuilder.AddColumn<DateTime>(
                name: "BetterName_Created",
                table: "Samurais",
                nullable: false,
                defaultValue: new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified));

    migrationBuilder.AddColumn<string>(
                name: "GivenName",
                table: "Samurais",
                nullable: true);

    migrationBuilder.AddColumn<DateTime>(
                name: "BetterName_LastModified",
                table: "Samurais",
                nullable: false,
                defaultValue: new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified));

    migrationBuilder.AddColumn<string>(
                name: "SurName",
                table: "Samurais",
                nullable: true);
}

SamuraiContext.cs

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<SamuraiBattle>().HasKey(s => new { s.SamuraiId, s.BattleId });

    modelBuilder.Entity<Battle>().Property(b => b.StartDate).HasColumnType("Date");
    modelBuilder.Entity<Battle>().Property(b => b.EndDate).HasColumnType("Date");

    foreach (var entityType in modelBuilder.Model.GetEntityTypes())
    {
        modelBuilder.Entity(entityType.Name).Property<DateTime>("Created");  
        modelBuilder.Entity(entityType.Name).Property<DateTime>("LastModified");
    }

    modelBuilder.Entity<Samurai>().OwnsOne(s => s.BetterName).Property(b => b.GivenName).HasColumnName("GivenName");
    modelBuilder.Entity<Samurai>().OwnsOne(s => s.BetterName).Property(b => b.SurName).HasColumnName("SurName");
}

在我添加 GivenName/Surname 之前已经构建了 foreach 上下文,直到一切都按预期工作。但是在为列名添加最后两行之后,它添加了 BetterName_Created 和 BetterName_LastModified 为什么? (根据课程不应该)

PersonFullName.cs

public class PersonFullName
{
    public string SurName { get; set; }
    public string GivenName { get; set; }
    public string FullName => $"{GivenName} {SurName}";
    public string FullNameReverse => $"{SurName}, {GivenName}";

    public PersonFullName(string givenName, string surName)
    {
        SurName = surName;
        GivenName = givenName;
    }
}

Samurai.cs

public class Samurai
{
    public int Id { get; set; }
    public string Name { get; set; }
    public PersonFullName BetterName { get; set; }
    public List<Quote> Quotes { get; set; }
    public List<SamuraiBattle> SamuraiBattles { get; set; }
    public SecretIdentity SecretIdentity { get; set; }

    public Samurai()
    {
        Quotes = new List<Quote>();
        SamuraiBattles = new List<SamuraiBattle>();
    }
}

最好的问候, 阿德里亚诺。

【问题讨论】:

    标签: c# entity-framework entity-framework-core ef-core-2.1


    【解决方案1】:

    这是因为foreach 循环也为拥有的实体定义了影子属性。请记住,根据 EF Core 术语,拥有的实体仍然是实体,因此GetEntityTypes() 将它们包含在结果集中。

    EF Core 提供IsOwned 扩展方法,可用于识别它们并进行特殊处理,或者在这种特殊情况下,跳过它们:

    foreach (var entityType in modelBuilder.Model.GetEntityTypes().Where(t => !t.IsOwned())
    {
        // ...
    }
    

    此外,此类循环应该在发现所有实体和拥有的实体类型之后进行。如果PersonFullName 没有标记[Owned] 属性,请将foreach 移动到OwnsOne 调用之后(或者最好放在OnModelCreating 的末尾)。

    【讨论】:

    • 非常感谢mutch,两种方法都试过了。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-02-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-14
    • 2018-10-31
    • 1970-01-01
    相关资源
    最近更新 更多