C# 多对一迁移在外键长时间上失败
我有两种型号:C# 多对一迁移在外键长时间上失败,c#,entity-framework,C#,Entity Framework,我有两种型号: 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 { get; set; } } 当我尝试跑步时: dotnet ef迁移添加 我得到这个错误: 具有外键属性的
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 { get; set; }
}
当我尝试跑步时:
dotnet ef迁移添加
我得到这个错误:
具有外键属性的{'Id':long}无法以主
键{'Id':int},因为它不兼容。配置主体
密钥或一组兼容的外键属性
关系
更新:
新型号应能收集如下表格文本:
public class Customer
{
public int Id { get; set; }
public ICollection<Text> Texts { get; set; }
}
在EF上下文配置中,特别是在
HasForeignKey()
中,您应该指定Text
模型上的哪个属性应该是指向用户
模型的外键
由于User
模型的主键是int
,因此从Text
指向User
的外键自然也应该是int
我认为您犯的错误是,您正在将Text
的PK配置为关系Text
->User
的FK。尝试将您的文本更改为:
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();
使用EF-Core也有类似的问题,但不想在依赖实体文本中包含(在我的类中是等效的)UserId,只是为了使EF愉快。最终发现可以替换关系中使用的主键(UserId)
使用HasPrincipalKey()
modelBuilder.Entity()
.HasMany(t=>t.text)
.WithOne()
.HasPrincipalKey(u=>u.Text);
首先,请更改您的型号命名
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);
});
公共类文本
{
公共长Id{get;set;}
public int UserId{get;set;}//添加一个可以指向User.Id的外键
公共字符串主体{get;set;}//不能有名为“Text”的字符串属性。
公共虚拟用户所有者{get;set;}
}
公共类用户
{
公共int Id{get;set;}
公共虚拟ICollection文本{get;set;}=new HashSet();
}
builder.Entity(表=>
{
表.HasKey(x=>x.Id);
table.HasOne(x=>x.User)
.有许多(x=>x.text)
.HasForeignKey(x=>x.UserId)
.HasPrincipalKey(x=>x.Id)//x.Id);
//将阴影特性添加到模型中
表.属性(“用户ID”);
table.HasOne(x=>x.User)
.有许多(x=>x.text)
.HasForeignKey(“UserId”)//一个是int
,另一个是long
是的,但是我怎么能说密钥属性类型是一个longHad,一个几乎相似的caase。为了将来的参考,,,,[此链接]()有所帮助。从流行的答案来看…[Column(TypeName=“int”)]public long Id{get;set;}
应该可以。如果我添加一个新的模型:拥有相同的ICollectionText集合的客户。你的答案不起作用,没有一个解决方案可以让我保存“自然”行为吗?你能详细说明我的答案如何不起作用以及你添加了什么模型吗?也许还需要一些代码?不可能改变自然行为因为外键应该唯一标识另一个表中的行。如果该行的标识(主键)是一个int
,那么您可以用来识别该行的唯一数据类型是int
,否则就无法识别它。我仍然不确定您试图实现什么。客户模型与用户
模型相同。此外,您还没有修复外键问题。如果1用户
可以有多个文本
,即使您有相同类型的ID,如果没有文本
上的附加(UserId
)属性,也不可能实现这种关系。哦,现在我明白了,非常感谢您的解释!
e.HasMany(o => o.Texts).WithOne().HasForeignKey(d => d.UserId).IsRequired();
modelBuilder.Entity<User>()
.HasMany(t => t.Texts)
.WithOne()
.HasPrincipalKey(u => u.Text);
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);
});
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);
});