Два ссылающихся на себя отношения один ко многим - PullRequest
0 голосов
/ 29 августа 2018

Это мой первый вопрос, поэтому, если есть проблемы с форматированием или неясные формулировки, пожалуйста, не стесняйтесь, сообщите мне.

У меня есть объект Item, который, помимо других свойств, имеет две ссылки на другие элементы ("GlobalItem" и "DepositItem") в одном и том же DBSet.

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? Может кто-нибудь найти недостаток в моем дизайне?

С наилучшими пожеланиями и спасибо за ваши усилия,

Ответы [ 3 ]

0 голосов
/ 29 августа 2018

Нет ничего плохого в этой модели. Возможно, ваша база данных должна быть воссоздана.

См:

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])
)
0 голосов
/ 30 августа 2018

Модель элемента и отображение в порядке.

Проблема была вызвана старым свойством навигации, также называемым «DepositItem», в другом объекте, который не был отображен в базе данных.

0 голосов
/ 29 августа 2018

Я предлагаю ваш объект должен быть

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() { }
}
...