我似乎无法正确理解 Foo 和 Bar 之间的关系。
public class Foo
{
[Key]
public int Id { get; set; }
public int Name { get; set; }
public virtual Bar Bar { get; set; }
}
public class Bar
{
[Key]
public int Id { get; set; }
public int Name { get; set; }
public int FooId { get; set; }
public virtual Foo Foo { get; set; }
}
通过这种结构我通常会
public virtual ICollection<Bar> Bars { get; set; }
在Foo中,但在这种情况下,这不是我数据的可行表示。
你看......
Foo 并不总是有 Bar
...但...
Bar 将始终具有 Foo ,并且其
public class MyContext : DbContext
{
public DbSet<Foo> Foos { get; set; }
public DbSet<Bar> Bars { get; set; }
protected override void OnModelCreating(System.Data.Entity.DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
// ...............
modelBuilder.Entity<Foo>()
.HasOptional(cpi => cpi.Bar)
.WithRequired(api => api.Foo);
// ...............
}
}
我尝试过多次尝试来定义这种关系,但似乎无法做到正确!我也可以为Foo添加一个可以为空的BarId,如果这样可以让我做我想做的事(但我不愿意)。 (参见编辑1)
我已经搜索了很多(并搜索并尝试过)许多类似(但不相同)的堆栈溢出帖子。
任何意见都会受到赞赏。
由于
编辑1(响应消费者评论):
这些表已经存在于许多实时环境中并且充满了数据,因此我想在不编辑db表定义的情况下找到解决方案......但如果不可能,我可以添加一列来实现我的目标需要。
以前我把它定义为......
public virtual ICollection<Bar> Bars { get; set; }
...但是对于我使用这些表格编写的代码,这不起作用。
编辑2:
当我尝试添加一个Bar时,上面的代码会出现以下错误。
“当IDENTITY_INSERT设置为OFF时,无法在表格'Bar'中为标识列插入显式值。”
身份插入没有关闭,我将它用于所有表,除非在这个实例中,EF似乎根据我对这些表的定义将其关闭。
答案 0 :(得分:0)
所以你真正的问题是
当IDENTITY_INSERT设置为OFF时,无法在表'Bar'中为identity列插入显式值
首先,此错误消息表示:您正在尝试将值插入标识列,当前配置为不允许该操作(关闭)。
实体框架可能会尝试插入零,因为您没有告诉EF关于身份列;这意味着您需要明确告诉EF您的此列正在从数据库中生成您的ID ...
protected override void OnModelCreating(System.Data.Entity.DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<Foo>()
.HasOptional(cpi => cpi.Bar)
.WithRequired(api => api.Foo);
// needed
modelBuilder.Entity<Bar>()
.HasKey(b => b.Id)
.Property(b => b.Id)
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
}
答案 1 :(得分:0)
我们试试DataAnnotations
吗?
public class Foo
{
public int Id { get; set; }
public string Name { get; set; }
public virtual Bar Bar { get; set; }
}
public class Bar
{
[Key, ForeignKey("Foo")]
public override int Id {get;set;}
public string Name { get; set; }
public virtual Foo Foo { get; set; }
}
答案 2 :(得分:0)
对象可以为空,因此可选的关系不需要您执行与.HasOptional()
声明不同的任何操作。
但是,你的关系中缺少外键。
public class Foo
{
[Key]
public int Id { get; set; }
public int Name { get; set; }
public int BarId { get; set; } // Add this!
[ForeignKey(nameof(BarId))] // Add this!
public virtual Bar Bar { get; set; }
}
public class Bar
{
[Key]
public int Id { get; set; }
public int Name { get; set; }
public int FooId { get; set; }
[ForeignKey(nameof(FooId))] // Add this!
public virtual Foo Foo { get; set; }
}