C# 无法确定类型之间关联的主体端-实体框架错误,同一类之间的类关系
使用下面的类,并尝试在数据库中查找记录返回错误。 使用C#、MVC4、实体框架4和SQL Server 2012数据库 错误 等级 数据库FKC# 无法确定类型之间关联的主体端-实体框架错误,同一类之间的类关系,c#,.net,entity-framework,asp.net-mvc-4,C#,.net,Entity Framework,Asp.net Mvc 4,使用下面的类,并尝试在数据库中查找记录返回错误。 使用C#、MVC4、实体框架4和SQL Server 2012数据库 错误 等级 数据库FK 错误是因为类名Usuario与属性public virtual Usuario UsuarioAlt{get;set;} 不能将同一类型用作导航属性。这里的问题是导航属性错误。想想SQL数据库表,同一个唯一主键可以是同一个表中的外键吗?您需要外键来自另一个表 实体框架使用导航属性来确定POCO和数据库表之间的实体关系模型 您希望为关系使用不同的类。如果您
错误是因为类名
Usuario
与属性public virtual Usuario UsuarioAlt{get;set;}
不能将同一类型用作导航属性。这里的问题是导航属性错误。想想SQL数据库表,同一个唯一主键可以是同一个表中的外键吗?您需要外键来自另一个表
实体框架使用导航属性来确定POCO和数据库表之间的实体关系模型
您希望为关系使用不同的类。如果您有第二个同名的类,请使用名称空间别名,这样运行时就可以知道这两个类之间的区别,现在它就像一个引用自身的类
你应该写你的模型如下
public class Usuario
{
[Key]
public int UsuarioID { get; set; }
public string Name { get; set; }
public int UsuCad { get; set; }
public int UsuAlt { get; set; }
public virtual SomeSecondClass SomeSecondClass { get; set; }
public virtual SomeThirdClass SomeThirdClass { get; set; }
}
public class SomeSecondClass
{
public int SomeSecondClassID { get; set;}
// More properties
}
public class SomeThirdClass
{
public int SomeThirdClassID { get; set;}
// More properties
}
回复
在搜索了很多之后,我发现了一个关于使用InverseProperty
然后代码看起来像这样。此属性ForeignKey
用于挂载链接和属性InverseProperty
,以通知字段依赖于此其他营地,并反转外键
谢谢你的帮助
public class Usuario
{
[Key]
public int UsuarioID { get; set; }
public string Nome { get; set; }
public int UsuCad { get; set; }
public int UsuAlt { get; set; }
[ForeignKey("UsuCad")]
[InverseProperty("UsuarioID")]
public virtual Usuario UsuarioCad { get; set; }
[ForeignKey("UsuAlt")]
[InverseProperty("UsuarioID")]
public virtual Usuario UsuarioAlt { get; set; }
}
我不能100%确定您在这里想要实现什么样的db模式。我的假设是,您希望具有同一表的外键。在你的评论中,你说你想要一对一的关系。从技术上讲,这是不可能的。因为在尝试插入第一条记录时,需要为外键列提供一个值。该值应为现有记录的Id。等待我们还没有任何记录 因为1-1在这里并不实际,所以应该建立一对零/一的关系。这意味着您的外键列应该是可空的,这样您就可以在外键列中插入具有
NULL
值的第一条记录
我很难理解您的模型和属性名称。因此,我将使用一个每个人都能理解的通用类/表,但需要满足您的特定要求(自引用外键)
我没有使用数据注释,我使用的是Fluent API
愚蠢的业务需求/假设是:
- 一个人可能有父母,也可能没有父母
- 一个人可能有孩子,也可能没有孩子
public class Person
{
public int Id { set; get; }
public string Name { set; get; }
public virtual Person Parent { set; get; }
public virtual Person Kid { set; get; }
}
var db = new MyDbContext();
var myMom = new Person {Name = "Indira"};
var me = new Person {Name = "Shyju", Parent = myMom};
var myDaughter = new Person { Name = "Gauri", Parent = me};
db.Persons.Add(myMom);
db.Persons.Add(me);
db.Persons.Add(myDaughter);
db.SaveChanges();
现在要使用fluentapi控制关系,我们需要转到DBContext类并重写OnModelCreating
方法
public class MyDbContext : DbContext
{
public MyDbContext() : base("MyConnectionStringName") { }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Person>().HasKey(d => d.Id)
.HasOptional(m => m.Kid).WithOptionalPrincipal(d=>d.Parent);
base.OnModelCreating(modelBuilder);
}
public DbSet<Person> Persons { set; get; }
}
并且,您的ParentId列中的数据在同一个表的ID列中有一个外键
外键存在吗?外键存在于数据库@Papa中。有代码优先和数据库优先两种方法。不过我最喜欢的是approach@marlon.tiedt您期望的数据库结构是什么?你能说出你想要建立什么样的关系吗?一对多/一/零?关系是一对一@shyjub,但这样我将不得不复制类?不,你不会有重复的类。我已经扩展了代码,希望它能有所帮助。这是代码优先的方法。使用EF约定。阅读这个博客。如果有自引用表,则可以使用与EF中的类同名的属性。@SWeko不能使用与导航属性相同的类型。这里的问题是导航属性错误。想想SQL数据库表,同一个唯一主键可以是同一个表中的外键吗?您需要外键来自另一个表。@SWeko实体框架使用导航属性来确定POCO和数据库表之间的实体关系模型
public class Person
{
public int Id { set; get; }
public string Name { set; get; }
public virtual Person Parent { set; get; }
public virtual Person Kid { set; get; }
}
public class MyDbContext : DbContext
{
public MyDbContext() : base("MyConnectionStringName") { }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Person>().HasKey(d => d.Id)
.HasOptional(m => m.Kid).WithOptionalPrincipal(d=>d.Parent);
base.OnModelCreating(modelBuilder);
}
public DbSet<Person> Persons { set; get; }
}
var db = new MyDbContext();
var myMom = new Person {Name = "Indira"};
var me = new Person {Name = "Shyju", Parent = myMom};
var myDaughter = new Person { Name = "Gauri", Parent = me};
db.Persons.Add(myMom);
db.Persons.Add(me);
db.Persons.Add(myDaughter);
db.SaveChanges();