Можно ли сначала использовать столбец PK в качестве дискриминатора в коде Entity Framework? - PullRequest
2 голосов
/ 18 ноября 2011

Сначала я пытаюсь использовать код Entity Framework, чтобы сопоставить простую таблицу поиска с иерархией типов и хочу использовать первичный ключ таблицы в качестве столбца дискриминатора для объекта «таблица на иерархию».Более актуально, я пытаюсь заставить это работать с существующей базой данных.

Вот пример надуманного приложения, которое я собрал, пытаясь выяснить, могу ли я заставить его работать или нет:

using System;
using System.ComponentModel.DataAnnotations;
using System.Data.Entity;
using System.Data.Entity.Infrastructure;

namespace EfTest
{
    public abstract class Base
    {
        public int LookupId { get; set; }

        public String Name { get; set; }

        public abstract String GetTest();
    }

    public class Derived1 : Base
    {
        public override string GetTest() { return Name + "1"; }
    }

    public class Derived2 : Base
    {
        public override string GetTest() { return Name + "2"; }
    }

    public class Derived3 : Base
    {
        public override string GetTest() { return Name + "3"; }
    }

    class Program
    {
        static void Main(string[] args)
        {
            Database.SetInitializer<MyContext>(new DropCreateDatabaseIfModelChanges<MyContext>()); 
            using(var context = new MyContext())
            {
                foreach (var item in context.Lookups)
                {
                    Console.WriteLine("{0} {1} {2}", item.LookupId, item.Name, item.GetType().FullName);
                }
            }
            Console.ReadKey();
        }
    }

    public class MyContext : DbContext
    {
        public DbSet<Base> Lookups { get; set; }

        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            var config = modelBuilder.Entity<Base>();

            config.HasKey(e => e.LookupId).ToTable("dbo.Lookup");

            config.Property(e => e.LookupId)
                .HasColumnName("LookupId")
                .IsRequired()
                .HasDatabaseGeneratedOption(DatabaseGeneratedOption.None);

            config.Property(e => e.Name)
                  .IsRequired()
                  .HasColumnName("Name")
                  .HasMaxLength(32)
                  .HasColumnType("varchar");

            config.Map<Derived1>(e => e.Requires("LookupId").HasValue(1).IsRequired());
            config.Map<Derived2>(e => e.Requires("LookupId").HasValue(2).IsRequired());
            config.Map<Derived3>(e => e.Requires("LookupId").HasValue(3).IsRequired());

            //config.Map<Derived1>(e => e.Requires("Name").HasValue("Item1").IsRequired());
            //config.Map<Derived2>(e => e.Requires("Name").HasValue("Item2").IsRequired());
            //config.Map<Derived3>(e => e.Requires("Name").HasValue("Item3").IsRequired());
        }
    }
}

Однако возникает исключение:

Проблема при отображении фрагментов, начиная со строки 24: сопоставляется элемент условия «Base.LookupId» с условием, отличным от «IsNull = False».Либо удалите условие для Base.LookupId, либо удалите его из сопоставления.

Я также пытался различать столбец «Имя» с похожими результатами.

Ошибки выглядят какон жаловался на то, что я пытаюсь отобразить в базу данных столбец, который можно обнулять, однако в таблице, которая фактически создается, оба столбца помечены как ненулевые, как я и ожидал.

Это то, что я пытаюсь сделатьпросто не поддерживается EF?

1 Ответ

0 голосов
/ 18 ноября 2011

Это невозможно. Каждый столбец может иметь только одно специальное назначение в отображении. Наличие столбца в качестве ключа и дискриминатора - две специальные цели. Столбец Дискриминатор имеет особое значение выбора правильного типа, который должен быть материализован, и потому, что в этом случае он не должен присутствовать в отображаемой сущности (вы не можете установить его из своего приложения). Также некорректно иметь дискриминатор в столбце, который должен быть уникальным.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...