LINQ, объект, который реализует интерфейс и исключение в сопоставлении

Я использую шаблон репозитория с LINQ, есть IRepository.DeleteOnSubmit (T Entity). Он работает нормально, но когда у моего класса сущности есть интерфейс, например:

public interface IEntity { int ID {get;set;} }

public partial class MyEntity: IEntity {

    public int ID { 
        get { return this.IDfield; }
        set { this.IDfield=value;  }
    }
}

а затем пытаюсь удалить какой-то объект вроде этого:

IEntity ie=repository.GetByID(1);
repoitory.DeleteOnSubmit(ie);

бросает
Член IEntity.ID не поддерживает преобразование в SQL.

получение данных из БД работает, а вот удаление и вставка - нет. Как использовать интерфейс с DataContext?


Вот он:
Сообщение об исключении: Член MMRI.DAL.ITag.idContent не поддерживает преобразование в SQL.

Код:

var d = repContent.GetAll().Where(x => x.idContent.Equals(idContent));
foreach (var tagConnect in d)    <- error line
{
    repContet.DeleteOnSubmit(tagConnect);

(он получает все теги из БД и удаляет их)

И трассировка стека:

[NotSupportedException: The member 'MMRI.DAL.ITag.idContent' has no supported translation to SQL.]
   System.Data.Linq.SqlClient.Visitor.VisitMember(SqlMember m) +621763
   System.Data.Linq.SqlClient.SqlVisitor.Visit(SqlNode node) +541
   System.Data.Linq.SqlClient.SqlVisitor.VisitExpression(SqlExpression exp) +8
   System.Data.Linq.SqlClient.SqlVisitor.VisitBinaryOperator(SqlBinary bo) +18
   System.Data.Linq.SqlClient.Visitor.VisitBinaryOperator(SqlBinary bo) +18
   System.Data.Linq.SqlClient.SqlVisitor.Visit(SqlNode node) +196
   System.Data.Linq.SqlClient.SqlVisitor.VisitExpression(SqlExpression exp) +8
   System.Data.Linq.SqlClient.SqlVisitor.VisitSelectCore(SqlSelect select) +46
   System.Data.Linq.SqlClient.Visitor.VisitSelect(SqlSelect select) +20
   System.Data.Linq.SqlClient.SqlVisitor.Visit(SqlNode node) +1024
   System.Data.Linq.SqlClient.SqlProvider.BuildQuery( ...

Когда я пытаюсь украсить частичный класс:

[Column(Storage = "_idEvent", DbType = "Int NOT NULL", IsPrimaryKey = true)]
public int idContent
{ get { return this.idEvent; } set { this.idEvent=value; } }

выдает ошибку «Недопустимое имя столбца idContent».

Stack overflow - это не форум. Некоторые из материалов, которые вы (и другие) опубликовали как «Ответ» на вопрос, на самом деле должны быть «комментариями». Вы также можете редактировать исходный вопрос и любой ответ.

jeroenh 15.01.2010 13:19
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
9
1
2 855
4

Ответы 4

Попробуй это:

using System.Data.Linq.Mapping;

public partial class MyEntity: IEntity 
 {    [Column(Storage = "IDfield", DbType = "int not null", IsPrimaryKey=true)]
      public int ID 
       {         
          get { return this.IDfield; }        
          set { this.IDfield=value;  }    
       } 
 }

Это работает для меня -

public partial class MyEntity: IEntity 
 {    [Column(Name = "IDfield", Storage = "_IDfield", IsDbGenerated = true)]
      public int ID 
       {         
          get { return this.IDfield; }        
          set { this.IDfield=value;  }    
       } 
 }

К сожалению, с выполнением вышеуказанного есть проблемы - social.msdn.microsoft.com/Forums/en-US/linqtosql/thread/… Внизу страницы есть ссылка на ошибку, зарегистрированную в MS Connect. Надеюсь, некоторые из вас проголосуют за него, чтобы на него можно было взглянуть - это проблема, которая уже давно меня раздражает ...

Frank Tzanabetis 28.01.2010 08:54

Для преобразования вашего запроса LINQ в реальный SQL Linq2SQL проверяет переданное вами выражение. Проблема в том, что вы не предоставили достаточно информации, чтобы L2S мог преобразовать свойство «ID» в фактическое имя столбца БД. Вы можете добиться желаемого, убедившись, что L2S может отображать «ID» в «IDField».

Это должно быть возможно с использованием подхода, представленного в ответах.

Если вы используете конструктор, вы также можете просто переименовать свойство класса «IDField» в «ID» с дополнительным преимуществом, заключающимся в том, что вам больше не придется явно реализовывать свойство «ID» в частичном классе, то есть в частичном классе. определение MyEntity просто становится:

public partial class MyEntity: IEntity 
{    
}

Похоже, что Microsoft отказалась от поддержки оператора == в интерфейсах при использовании linq-to-sql в MVC4 (или, возможно, он никогда не поддерживался). Однако вы можете использовать i.ID.Equals(someId) вместо оператора ==.

Преобразование IQueryable в IEnumerable работает, но не следует использовать! Причина в том, что IQueryable имеет забавную реализацию IEnumerable. Какой бы метод linq вы ни использовали на IQueryable через интерфейс IEnumerable, запрос будет выполнен первым, все результаты будут извлечены в память из БД и, в конечном итоге, будет запущен метод локально для данных (обычно эти методы будут переведены в SQL и выполняется в БД). Представьте, что вы пытаетесь получить одну строку из таблицы, содержащей миллиард строк, выбирая все из них только для того, чтобы выбрать одну (и все становится намного хуже при неосторожном преобразовании IQueryable в IEnumerable и ленивой загрузке связанных данных).

По-видимому, у Linq нет проблем с использованием оператора == с интерфейсами для локальных данных (так что затрагивается только IQueryable), а также с Entity Frameworks (по крайней мере, я слышал).

Действительно странно, что == не поддерживается. В любом случае, спасибо за ответ. i.ID.Equals(someId) у меня работает нормально.

mykhailovskyi 22.07.2015 13:49

Другие вопросы по теме