Ошибки валидации Entity Framework при вставке с затененным свойством

1

Рассмотрим следующий сценарий:

public abstract class Entity
{
    public object Id { get; set; }
}

public abstract class Entity<T> : Entity
{
    public new T Id { get; set; }
}

public class Foo : Entity<Guid>
{
}

Если у меня есть следующий код:

var foo = new Foo { Id = Guid.NewGuid() };
db.Foos.Add(foo);
db.SaveChanges();

Я получаю исключение DbEntityValidation говорящее, что Id не разрешено иметь значение null. Если я отлаживаю, я вижу, что Foo.Id действительно имеет значение, но если я Foo.Id в базовый объект до уровня Entity, Id будет там null, и, похоже, это то, что Entity Framework использует для проверки а не без тени. Я чувствую, что у меня отсутствует что-то действительно основное; может быть, я просто не имел достаточно кофе сегодня утром. Любые идеи, что может быть проблемой?

  • 0
    Может ли это быть как-то связано с некой ленивой загрузкой?
  • 0
    Что делать, если вы сделали это var foo = new Foo(); foo.Id = Guid.NewGuid(); db.Foos.Add(foo); db.SaveChanges();
Теги:
entity-framework

2 ответа

1
Лучший ответ

Проблема в том, что

public new T Id { get; set; }

... в Entity<T> скрывает свойство Id в Entity. Если вы это сделаете:

var foo = new Foo { Id = Guid.NewGuid() };
Entity entity = foo as Entity;
Console.WriteLine(entity.Id);

... что не собирается возвращать Guid, он будет возвращать то, что осталось за Entity.Id, который является объектом, который не был установлен.

Редактировать:

Крис придумал это, что должно хорошо работать.

public abstract class Entity<T> : Entity
{
    public new T Id
    {
        get { return (T)base.Id; }
        set { base.Id = value; }
    }
}
  • 0
    На самом деле, ваш ответ, хотя технически он не решил мою проблему, заставил меня задуматься о возможном решении.
1

Да, я пропустил что-то простое: Entity Framework некомпетентен и не поддерживает свойство shadowing. Я думал, что это произошло, потому что в прошлом я успешно использовал теневое копирование для изменения атрибутов свойств (например, сделать свойство, требуемое только в подклассе), но я никогда не зашел так далеко, чтобы фактически попытаться изменить тип.

ОБНОВИТЬ

Мне пришло в голову, что если бы я просто установил базовое свойство с правильным значением, все было бы хорошо. Итак, я изменил класс Entity<T> на следующее:

public abstract class Entity<T> : Entity
{
    public new T Id
    {
        get { return (T)base.Id; }
        set { base.Id = value; }
    }
}

Исключение ушло, и объект был успешно сохранен в базе данных. Есть ли какие-то непредвиденные последствия для этого, что мне не хватает?

  • 0
    Это должно работать нормально, я бы подумал.
  • 0
    Я действительно чувствую, что вы намекаете на что-то подобное, но никогда не выходили и не говорили этого. Именно ваш ответ положил начало моему мозгу, но я действительно думаю, что этот код должен быть в принятом ответе. Если вы хотите сорвать его и обновить свой ответ, я убью свой и приму ваш.
Показать ещё 1 комментарий

Ещё вопросы

Сообщество Overcoder
Наверх
Меню