问题
I'm new to Entity Framework and I'm learning atm with the Pluralsight courses from Julie Lerman. I'm watching the 2nd course "Entity Framework Core 2: Mappings" but I'm using EF Core 2.1.
Edit: So I decided comment everything out and follow the course again and it is working now BUT the generated migration in generating 2 columns that shouldn't be there:
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");
}
the foreach context has been build already before I add the GivenName/Surname, until that everything is working as intended. But after adding the last 2 rows for the column name it adds BetterName_Created and BetterName_LastModified why? (according to the course it shouldn't)
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>();
}
}
Best regards, Adriano.
回答1:
It's because the foreach
loop defines shadow properties for owned entities as well. Remember that by the EF Core terminology owned entities are still entities, so GetEntityTypes()
includes them in the result set.
EF Core provides IsOwned extension method which can be used to identify them and do special processing, or in this particular case, just skip them:
foreach (var entityType in modelBuilder.Model.GetEntityTypes().Where(t => !t.IsOwned())
{
// ...
}
Also, such loops should be after discovering all entity and owned entity types. In case PersonFullName
is not marked with [Owned
] attribute, move the foreach
after the OwnsOne
calls (or better at the end of the OnModelCreating
).
来源:https://stackoverflow.com/questions/52888876/shadowproperties-being-reached-by-foreach-before-being-created