两个自指一对多关系



这是我的第一个问题,所以如果有格式问题或表述不清楚,请不要急于告诉我。

我有一个名为 Item 的实体,除了其他属性外,它还有两个指向同一 DBSet 中其他项目("GlobalItem"和"DepositItem"(的链接。

public class Item
{
public int ItemID { get; private set; }

public virtual Item GlobalItem { get; set; }
public virtual Item DepositItem { get; set; }
protected Item() { }
}

映射是这样完成的:

public ItemMap()
{
HasKey(o => o.ItemID);
ToTable("Item", "dbo");
// Relationships
HasOptional(o => o.GlobalItem)
.WithMany()
.Map(m => m.MapKey("GlobalItemID"));
HasOptional(o => o.DepositItem)
.WithMany()
.Map(m => m.MapKey("DepositItemID"));
}

构建过程成功,但是当我尝试 GetAll(( 时,会抛出以下异常:

System.Data.Entity.Core.EntityCommandExecutionException:"执行命令定义时出错。有关详细信息,请参阅内部例外。

内部异常:

SqlException:列名"DepositItem_ItemID"无效。

列名"DepositItem_ItemID"无效。

列名"DepositItem_ItemID"无效。

我知道此异常通常是由简单的映射错误引起的,但在这种情况下,我陷入了困境,因为我确保 ColumnName 和 MapKey 是正确的,并且所有常见的解决方法(例如在实体中显式定义 DepositItemID 并使用.HasForeignKey(k = k.DepositItemID)而不是以前的映射定义(并没有改变任何东西。

EF6 是否存在多个自引用虚拟属性的一般性问题?有人可以向我解释一下,为什么DepositItem忽略了映射键,而GlobalItem却没有忽略映射键?有人能发现我的设计中的缺陷吗?

最诚挚的问候和感谢您的努力,

这个模型没有错。 也许您的数据库需要重新创建。

看:

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Data.Entity;
using System.Data.SqlClient;
using System.Linq;
namespace Ef6Test
{
public class Item
{
public int ItemID { get; private set; }
//public virtual Category Category { get; set; }
public string Description { get; set; }
public string ItemLookupCode { get; private set; }
public virtual Item GlobalItem { get; set; }
public virtual Item DepositItem { get; set; }
public bool IsDeleted { get; set; }
//public virtual ItemExtension ItemExtension { get; set; }

public Item() { }
}
class Db : DbContext
{
public DbSet<Item> Items { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<Item>().HasKey(o => o.ItemID);
modelBuilder.Entity<Item>().ToTable("Item", "dbo");
// Relationships
//HasRequired(t => t.Category)
//    .WithMany(o => o.Items)
//    .Map(m => m.MapKey("CategoryID"));
modelBuilder.Entity<Item>().HasOptional(o => o.GlobalItem)
.WithMany()
.Map(m => m.MapKey("GlobalItemID"));
modelBuilder.Entity<Item>().HasOptional(o => o.DepositItem)
.WithMany()
.Map(m => m.MapKey("DepositItemID"));
//HasOptional(o => o.ItemExtension)
//    .WithRequired(o => o.Item);

}

class Program
{

static void Main(string[] args)
{
Database.SetInitializer(new DropCreateDatabaseAlways<Db>());

using (var db = new Db())
{
db.Database.Log = m => Console.WriteLine(m);
db.Database.Initialize(true);
var items = db.Items.ToList();

}

Console.WriteLine("Hit any key to exit");
Console.ReadKey();
}
}
}
}

创建

CREATE TABLE [dbo].[Item] (
[ItemID] [int] NOT NULL IDENTITY,
[Description] [nvarchar](max),
[ItemLookupCode] [nvarchar](max),
[IsDeleted] [bit] NOT NULL,
[DepositItemID] [int],
[GlobalItemID] [int],
CONSTRAINT [PK_dbo.Item] PRIMARY KEY ([ItemID])
)

我建议你的对象应该是

public class Item
{
public int ItemID { get; private set; }
public int? GlobalItemID { get; set; }
public int? DepositItemID { get; set; }
[ForeignKey("GlobalItemID")]
public Item GlobalItem { get; set; }
[ForeignKey("DepositItemID")]
public Item DepositItem { get; set; }
protected Item() { }
}

项目模型和映射都很好。

该问题是由另一个实体中的旧导航属性(也称为"DepositItem"(引起的,该属性未在数据库中映射。

最新更新