多对一次迁移在外键上失败了

时间:2016-11-28 12:14:56

标签: c# entity-framework

我有2个模特

 public class Text
  {
    public long Id { get; set; }
   public string Text{ get; set; }
}


 public class User
  {
    public int Id { get; set; }
   public ICollection<Text>Texts
}

我建立在用户身上的模型是

e.HasMany(o => o.Texts).WithOne().HasForeignKey(d => d.Id).IsRequired();

当我尝试跑步时:

  

dotnet ef迁移添加

我得到了 - &gt;

  

使用外键属性{'Id':long}无法定位主要属性   key {'Id':int}因为它不兼容。配置主体   密钥或一组兼容的外键属性   关系。

更新:

新模型应该能够拥有表格的集合,如:

 public class Customer
 {
   public int Id { get; set; }
   public ICollection<Text>Texts  { get; set; }
 }

....     e.HasMany(o =&gt; o.Texts).WithOne()。HasForeignKey(d =&gt; d.Id).IsRequired();

4 个答案:

答案 0 :(得分:2)

在EF上下文配置中,特别是在HasForeignKey()中您应该指定 Text模型上的哪个属性应该是指向User模型的外键?

由于User模型的主键是int,因此从Text指向User的外键当然也应该是int

我认为您犯的错误是您将Text的PK配置为关系Text的FK - &gt; User。尝试将您的Text模型更改为:

public class Text
{
   public long Id { get; set; }
   public string Text{ get; set; }
   public int UserId { get; set; }
}

您的配置为:

e.HasMany(o => o.Texts).WithOne().HasForeignKey(d => d.UserId).IsRequired();

答案 1 :(得分:2)

使用EF Core有类似的问题,但不想在依赖实体Text上包含(我的类中的等价物)UserId,只是为了制作快乐的EF。终于发现你可以替换关系中使用的主键(UserId) 使用HasPrimaryKey()

    modelBuilder.Entity<User>()
        .HasMany(t => t.Texts)
        .WithOne()
        .HasPrincipalKey(u => u.Text);

答案 2 :(得分:1)

首先,请更改您的模型命名,

public class Text
{
    public long Id { get; set; }
    public int UserId { get; set; }// add a foreign key that could point to User.Id
    public string Body { get; set; }//you cannot have a string property called "Text".
    public virtual User Owner { get; set; }
}
public class User
{
    public int Id { get; set; }
    public virtual ICollection<Text> Texts { get; set; } = new HashSet<Text>();
}

builder.Entity<Text>(table =>
        {
            table.HasKey(x => x.Id);

            table.HasOne(x => x.User)
            .WithMany(x => x.Texts)
            .HasForeignKey(x => x.UserId)
            .HasPrincipalKey(x => x.Id)//<<== here is core code to let foreign key userId point to User.Id.
            .OnDelete(DeleteBehavior.Cascade);
        });

我们必须弄清楚引用哪个键的原因是多个主键。我在MSDN中看过一次,但找不到它。

您可以对外键使用阴影属性,它现在看起来很流行。

public class Text
{
    public long Id { get; set; }
    public string Body { get; set; }
    public virtual User Owner { get; set; }
}
public class User
{
    public int Id { get; set; }
    public virtual ICollection<Text> Texts { get; set; } = new HashSet<Text>();
}

builder.Entity<Text>(table =>
        {
            table.HasKey(x => x.Id);

            // Add the shadow property to the model
            table.Property<int>("UserId");

            table.HasOne(x => x.User)
            .WithMany(x => x.Texts)
            .HasForeignKey("UserId")//<<== Use shadow property
            .HasPrincipalKey(x => x.Id)//<<==point to User.Id.
            .OnDelete(DeleteBehavior.Cascade);
        });

答案 3 :(得分:0)

您可以简单地删除所有迁移或生成该 ID 的迁移,删除数据库(如果它很小或没有数据)并添加一个干净的迁移