2014-11-27 4 views
1

Предположим, у нас есть таблица под названием Car с такими столбцами, как ID, Identification, ModelName, OwnerId и т. Д., Где OwnerId указывает на первичный ключ в таблице Owner. Это все хорошо, но тогда мы хотим добавить к машине водителя, так как мы хотим знать, кто управляет каждым автомобилем в определенное время.Почему LINQ выбрасывает исключение NotSupportedException?

Звучит прямо, верно? Просто создайте таблицу драйверов и добавьте новую нулевую (нет драйвера, если автомобиль находится в гараже и т. Д.) Int column под названием DriverId на стол Car, подключите его с помощью внешнего ключа, и мы будем рады.

Я сделал это и обновил EDMX в дизайнере модели, так что появилась новая таблица, столбец и внешний ключ. Все выглядит хорошо. Свойство DriverId и свойство навигации драйвера находятся там в сгенерированном коде, а также генерируется новый класс драйвера.

Теперь, когда я попытался использовать эту новую таблицу и подключить драйверы к автомобилям, есть что-то очень не так. Похоже, что LINQ не знает о столбце DriverId или внешнем ключе (свойство навигации) для драйвера.

  1. Если я пытаюсь получить автомобиль с данным водителем:

    Car car = (from c in db.Cars.Where(x => x.DriverId == driverId) select c).FirstOrDefault(); 
    

    Я ожидаю, чтобы получить автомобиль, если водитель в настоящее время вождения автомобиля или нуль в противном случае. Что я получаю сообщение об ошибке:

    System.NotSupportedException: The specified type member 'DriverId' is not supported in LINQ to Entities. Only initializers, entity members, and entity navigation properties are supported. 
    
  2. Допустим, мы хотим, чтобы добавить новый автомобиль с водителем:

    Car car = new Car{ blah, blah, etc, DriverId = driverId }; 
    db.Cars.Add(car); 
    db.SaveChanges(); 
    

    Это, кажется, работает хорошо. Новый автомобиль вставляется в базу данных. Единственное, что столбец DriverId имеет значение null, поэтому очевидно, что он не работает нормально ...

Я предполагаю, что все это связано. Я просто не понимаю, в чем проблема. Кто-нибудь знает, почему или какие-то предложения относительно того, что я могу попробовать?


EDIT:

автомобиля и водителя классы чисто сгенерированный код, поэтому я уверен, что они выглядят знакомыми:

[DataContract(IsReference = true)] 
[KnownType(typeof(Owner))] 
[KnownType(typeof(Driver))] 
public partial class Car 
{ 
    [DataMember] 
    public int ID { get; set; } 

    [DataMember] 
    public string Identification { get; set; } 

    [DataMember] 
    public Nullable<int> OwnerId { get; set; } 

    [DataMember] 
    public Nullable<int> DriverId { get; set; } 

    //Navigation properties 
    [DataMember] 
    public virtual Owner Owner { get; set; } 

    [DataMember] 
    public virtual Driver Driver { get; set; } 
} 

[DataContract(IsReference = true)] 
[KnownType(typeof (Car))] 
public partial class Driver 
{ 
    //Constructor 
    public Driver() 
    { 
     this.Cars = new HashSet<Car>(); 
    } 

    [DataMember] 
    public int ID { get; set; } 

    [DataMember] 
    public string Name { get; set; } 

    //Navigation properties 
    [DataMember] 
    public virtual HashSet<Car> Cars { get; set; } 
} 
+0

Не могли бы вы выслать код своего лица? некоторое отображение? –

+3

Если вы изменяете существующий EDMX, вам нужно сделать три изменения каждый раз, когда вы добавляете поле - добавьте его в модель хранилища, затем в концептуальную модель, а затем в картографию. Если один из этих трех отсутствует, он сломается. В отдельном примечании 'FirstOrDefault' берет предикат, поэтому вы можете написать' db.Cars.FirstOrDefault (x => x.DriverId == driverId) '. – dasblinkenlight

+0

@dasblinkenlight Чтобы обновить datamodel, я использую модель viewer/designer/thingie в Visual Studio. Щелкните правой кнопкой мыши -> Обновить модель из базы данных ... Я делал это сотни раз, и у меня никогда не было этой проблемы раньше. Я знаю, что вы можете пропустить «Куда» и просто поместить предикат в FirstOrDefault. ReSharper обычно скулит об этом;) – Eirik

ответ

0

Поскольку проблема, как представляется, возлагали и работа в прогрессах, я вставляю здесь обрезанное обсуждение как временный «ответ», просто чтобы оставить след работы и быть уверенным, что комментарии с фактами/мыслями не испаряются. Не стесняйтесь добавлять/обрезать все здесь.
Eirik: если вам удастся сузить его до нужных причин, напишите последующий ответ, объяснив, что было не так, и почему он скомпилировался без ошибок. Просто не забудьте «принять» это;) Или, если хотите, добавьте информацию в нижней части этого «чата». Я передал этот ответ, поэтому никаких баллов не будет.


Me: Я тоже думаю, что один из ваших моделей пошли десинхронизировано. (..) Одной из распространенных вещей было дублирование записей или не обновление идентификаторов между пространствами модели.Не могли бы вы попытаться восстановить EDMX с нуля, или у вас слишком много ручных изменений?


Эйрик:

Я испытал плохие обновления раньше и решить их путем удаления таблиц, связанных с моделью и затем запустить еще одно обновление, чтобы получить их readded. Что касается регенерации EDMX с нуля ... нет. У меня есть базовые изменения вручную, поэтому у меня просто нет времени, чтобы все это изменить. Я уже пытался удалить таблицы, участвующие в этой проблеме, и их без изменений перечислил. Такая же ошибка/проблема.


Me: Так как нав-реквизит генерируется слишком, я предполагаю, что у вас есть свойство Driver? Вы пытались использовать объекты вместо этого? Я имею в виду, db.Cars.Where(x => x.Driver.Id == driverId) select c и Car car = new Car{ blah, blah, etc, Driver = driverObject };? Если это работало, было бы указать свойство < -> столбец имен столкновение где-то (...)


Эйрик:

Изменение x.DriverId == driverId к x.Driver.ID = = DriverId приводит к тому же сообщению об ошибке (разрешены только инициализаторы, члены и свойства навигации). Драйвер должен быть признан навигационным свойством, но это не так. DriverId должен быть признан членом, но это не так. Вставка также не работает. То есть, он вставляет, но с Car.DriverId является нулевым.

Me: Nav реквизит не работает. Ваш EDMX запутан, (..) Теперь я пережевываю три раздела EDMX и проверяю, что все столбцы, реквизиты, navs и т. Д. Правильно ссылаются друг на друга. Также можно сделать еще один тест: создать новый edmx, содержащий только эти таблицы, не трогать его, оставить сгенерированные имена и (..) сравнить содержимое нового edmx со старым большим edmx и искать разницу. (..)


Эйрик:

Я создал новый тестовый проект и сгенерировал EDMX с нуля и материал работает как задумано. Поэтому я предполагаю, что это просто плохой случай обновления в дизайнере моделей. В настоящее время я просматриваю файлы EDMX и сравниваю содержимое. Пока нет решения, но я подозреваю, что найду его в будущем ... zzZzzZ..thanks для ввода до сих пор!

+0

Ох .. и еще одна вещь .. если вы напишете свой собственный ответ, напишите мне сообщение, я сниму его! – quetzalcoatl

+0

Я не знаю, стоит ли отвечать. Что я, наконец, сделал, чтобы решить это, нужно, чтобы коллега захватил изменения в базе данных, которые я недавно сделал, обновил его копию EDMX с новым материалом базы данных, передал свою обновленную версию EDMX на SVN, а затем я просто обновился, поэтому получил свою рабочую версию. "Задача решена". Вероятно, проблема возникла из-за плохого обновления данных, но мне кажется странным, что одна и та же ошибка возникает несколько раз подряд после удаления/добавления таблиц. – Eirik