Если у объекта есть несколько отношений, и я пытаюсь вставить одновременно данные на них, EF вызывает InvalidCastException.InvalidCastException: EF сбой при вставке объекта с несколькими отношениями
В качестве примера, представьте себе, эти классы домена:
public class Person : Entity<Guid>
{
public string Name { get; set; }
public ICollection<Watch> Watches { get; set; }
public ICollection<Shoe> Shoes { get; set; }
}
public class Shoe : Entity<Guid>
{
public string Brand { get; set; }
}
public class Watch : Entity<Guid>
{
public string Brand { get; set; }
}
Пример использования # 1 (отлично работает):
using (var context = new MultipleRelationshipsContext())
{
var watches =
new List<Watch>() {
new Watch { Brand = "Rolex" }
};
context.Set<Person>().Add(
new Person
{
Name = "Warren Buffett",
Watches = watches
}
);
}
Используйте случай # 2 (отлично работает тоже):
using (var context = new MultipleRelationshipsContext())
{
var shoes =
new List<Shoe>() {
new Shoe { Brand = "Cole Haan" }
};
context.Set<Person>().Add(
new Person
{
Name = "Barack Obama",
Shoes = shoes
}
);
}
Вариант использования № 3 (InvalidCastException):
using (var context = new MultipleRelationshipsContext())
{
var watches =
new List<Watch>() {
new Watch { Brand = "Casio" }
};
var shoes =
new List<Shoe>() {
new Shoe { Brand = "New Balance" }
};
context.Set<Person>().Add(
new Person
{
Name = "Steve Jobs",
Watches = watches,
Shoes = shoes
}
);
}
В третьем случае выбрано InvalidCastException, в котором говорится, что EF не может отличить от 'EntityFrameworkMultipleRelationships.Entities.Watch
до' EntityFrameworkMultipleRelationships.Entities.Shoe
'.
Я новичок в EF, но я думаю, что здесь происходит нечто неправильное.
Я бы приложил любые намеки, чтобы указать на возможное решение!
PD .: Чтобы проверить себя как можно быстрее, загрузите это решение VS2012: https://dl.dropboxusercontent.com/u/22887057/EntityFrameworkMultipleRelationships.zip. Следуйте за README.txt, чтобы создать базу данных по шаблону кода.
UPDATE
Как @ Крис отметил, что проблема в том, что EF считает обуви и смотреть объекты являются одинаковыми. Это было вызвано плохим реализованным избытком Equals. Это на самом деле является источником проблем:
public abstract class Entity<T>
{
[Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
[Column("Id")]
public T Id { get; set; }
public override bool Equals(object obj)
{
Entity<T> entityOfT = obj as Entity<T>;
if (entityOfT == null)
return false;
return object.Equals(this.Id, entityOfT.Id);
}
public override int GetHashCode()
{
return this.Id.GetHashCode();
}
}
Если два различных типа сущностей (как Watch
и Shoe
) имеют один и тот же Id, EF рассматривает их равными.
Добавление проверки времени выполнения для переопределения Equals учитывает тип объекта и поэтому решает эту проблему.
...
return this.GetType() == entityOfT.GetType() && object.Equals(this.Id, entityOfT.Id);
...
делает эту работу context.Set() .Add ( новый Person { Name = "Стив Джобс", часы = часы } ); –
Ehsan
Конечно, это тот же случай, что и # 1. –
У вас это исправлено? Я столкнулся с подобной проблемой, только она дает ошибку, когда у меня есть таблица, разделенная на два класса (сущности домена), и ошибка говорит, что она не может отбрасывать один на другой. http://stackoverflow.com/questions/19391238/how-to-save-an-object-graph-with-entityframework-lazy-load-disabled-proxy-disa –