7

在我的 ASP.NET Core 1.0、MVC6、EF7 Web 应用程序中,我添加了一个迁移,该迁移添加了一个新的相关表(和相应的模型)。我有以下模型快照:

[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");
        });
    }
}

团队.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; }
}

应用用户:

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; }
}

当我尝试更新数据库时,dnx 给了我以下错误:

导航属性“经理”不能添加到实体类型“团队”,因为实体类型是在影子状态中定义的,并且导航属性不能添加到影子状态。

实体类型处于“影子状态”意味着什么?有没有解决的办法?

4

4 回答 4

1

EF 文档解释了什么是影子属性:

您可以使用 Fluent API 配置阴影属性。一旦您调用了 Property - AC 的字符串重载,您就可以链接您对其他属性的任何配置调用。

如果提供给 Property 方法的名称 ( Property<...>("...")-AC) 与现有属性的名称- AC(影子属性或在实体类上定义的属性)匹配,则代码将配置该现有属性,而不是引入新的影子属性。

所以,我猜当实体至少有一个shadow 属性时实体处于 shadow 状态。

这意味着在使用 的字符串重载时应该非常小心Property<...>("..."),因为即使您不需要它们也可能会引入影子属性。结果,当需要创建数据库时,EF 抱怨影子状态下的实体不存在 CLR 类型。

使用nameof()而不是纯字符串可能会有所帮助。因此,过载看起来像Property<...>(nameof(...))哪个更安全。

最后,为了更接近点阴影,引入了属性来处理实体之间的关系。下面解释它:

按照惯例,只有在发现关系但在依赖实体类中找不到外键属性时才会创建影子属性。在这种情况下,将引入影子外键属性。

于 2016-10-25T08:51:24.163 回答
0

这个问题实际上与我的ApplicationDbContext班级有关。我没有手动创建迁移和更新ApplicationDbContextModelSnapshot,而是添加了ApplicationDbContext

public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
    // -- <snipped> --
    public DbSet<Team> Teams { get; set; }
    public ApplicationUser Manager { get; set; }
    public ApplicationUser Members { get; set; }

    protected override void OnModelCreating(ModelBuilder builder)
    {
        base.OnModelCreating(builder);

        builder.Entity<Team>().HasOne(typeof(ApplicationUser), "Manager")
            .WithOne("TeamManaging")
            .HasForeignKey(typeof(Team), "ManagerId")
            .HasPrincipalKey(typeof(ApplicationUser), "Id");
        builder.Entity<ApplicationUser>().HasOne(typeof(Team), "Team")
            .WithMany("Members")
            .HasForeignKey("TeamId");
    }
}

然后我学会了如何使用dnx ef migrations add [migration name].

通过这种方式,我成功地让我的网站正常工作,但如果有人可以回答,我仍然想知道“影子状态”是什么。

于 2016-01-29T18:38:33.790 回答
0

就我而言,当我在我的模型中删除外键但忘记在我的 ApplicationDbContext 构建模型中删除它时,我得到了这个错误。

于 2022-02-14T21:19:04.107 回答
-1

你读过https://github.com/aspnet/EntityFramework/issues/2801吗?您使用的实体框架版本不稳定,请尝试重新创建数据库。如果您的应用程序要进入生产环境,您应该考虑迁移到 EF 6.x。

于 2016-01-29T08:24:43.440 回答