Я использую шаблон репозитория с 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».





Попробуй это:
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. Надеюсь, некоторые из вас проголосуют за него, чтобы на него можно было взглянуть - это проблема, которая уже давно меня раздражает ...
Для преобразования вашего запроса 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) у меня работает нормально.
Stack overflow - это не форум. Некоторые из материалов, которые вы (и другие) опубликовали как «Ответ» на вопрос, на самом деле должны быть «комментариями». Вы также можете редактировать исходный вопрос и любой ответ.