In my ASP.NET Core 1.0, MVC6, EF7 web application, I'm adding a migration that adds a new related table (& corresponding model). I have the following model snapshot:
[DbContext(typeof(ApplicationDbContext))]
partial class ApplicationDbContextModelSnapshot : ModelSnapshot
{
protected override void BuildModel(ModelBuilder modelBuilder)
{
modelBuilder
.HasAnnotation("ProductVersion", "7.0.0-rc1-16348")
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
modelBuilder.Entity("Salesboost.Models.ApplicationUser", b =>
{
b.Property<string>("Id");
b.Property<int?>("TeamId");
b.HasKey("Id");
// -- <unrelated fields snipped> --
});
// -- <snipped> --
modelBuilder.Entity("Team", b =>
{
b.Property<int>("Id").ValueGeneratedOnAdd();
b.Property<string>("Name").IsRequired();
b.Property<string>("ManagerId").IsRequired();
b.HasKey("Id");
});
modelBuilder.Entity("Team", b =>
{
b.HasOne("ApplicationUser", "Manager")
.WithOne("TeamManaging")
.HasForeignKey("ManagerId");
});
}
}
Team.cs:
public class Team
{
public int Id { get; set; }
public string Name { get; set; }
public string ManagerId { get; set; }
public virtual ApplicationUser Manager { get; set; }
public virtual ICollection<ApplicationUser> Members { get; set; }
}
ApplicationUser:
public class ApplicationUser : Microsoft.AspNet.Identity.EntityFramework.IdentityUser
{
public int? TeamId { get; set; }
public virtual Team Team { get; set; }
public virtual Team TeamManaging { get; set; }
}
When I attempt to update the database, dnx gives me the following error:
The navigation property 'Manager' cannot be added to the entity type 'Team' because the entity type is defined in shadow state and navigations properties cannot be added to shadow state.
What does it mean for an entity type to be in "shadow state"? Is there a way around this?
Shadow properties are properties that aren't defined in your . NET entity class but are defined for that entity type in the EF Core model. The value and state of these properties are maintained purely in the Change Tracker.
The foreign key property 'InsurancePolicy. InsuranceSubjectID1' was created in shadow state because a conflicting property with the simple name 'InsuranceSubjectID' exists in the entity type, but is either not mapped, is already used for another relationship, or is incompatible with the associated primary key type.
The EF documentation explains what a shadow property is:
You can use the Fluent API to configure shadow properties. Once you have called the string overload of Property - A.C. you can chain any of the configuration calls you would for other properties.
If the name supplied to the Property method (
Property<...>("...")
- A.C.) matches the name of an existing property - A.C. (a shadow property or one defined on the entity class), then the code will configure that existing property rather than introducing a new shadow property.
So, I guess an entity is in shadow state when the entity is having at least one shadow property.
This means that you should be very careful when using the string overload of Property<...>("...")
, since this may introduce shadow properties even if you do not need them. As a result, when the database needs to be created EF complains that no CLR type exists for the entity in shadow state.
Using nameof()
instead of plain strings may help. Thus the overload would look like Property<...>(nameof(...))
which is safer.
And finally, to get closer to the point shadow properties are introduced to handle relationships between entities. The following explains it:
By convention, shadow properties are only created when a relationship is discovered but no foreign key property is found in the dependent entity class. In this case, a shadow foreign key property will be introduced.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With