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);

throws
У члена '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 ».»

18.08.2008 09:28:22
Переполнение стека это не форум. Некоторые материалы, которые вы (и другие) опубликовали как «ответ» на вопрос, должны быть «комментариями». Вы также можете редактировать оригинальный вопрос и любой ответ.
jeroenh 15.01.2010 10:19:16
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;  }    
       } 
 }
0
18.08.2008 09:33:29

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

public partial class MyEntity: IEntity 
 {    [Column(Name = "IDfield", Storage = "_IDfield", IsDbGenerated = true)]
      public int ID 
       {         
          get { return this.IDfield; }        
          set { this.IDfield=value;  }    
       } 
 }
3
15.01.2010 04:48:13
К сожалению, существуют проблемы с выполнением вышеуказанного: social.msdn.microsoft.com/Forums/en-US/linqtosql/thread/… В нижней части этой страницы есть ссылка на ошибку, зарегистрированную в MS Connect. Надеюсь, некоторые из вас смогут проголосовать, чтобы на нее взглянули - это проблема, которая меня давно уже раздражает ...
Frank Tzanabetis 28.01.2010 05:54:42

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

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

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

public partial class MyEntity: IEntity 
{    
}
0
15.01.2010 10:16:29

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

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

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

7
25.11.2015 12:54:19
Это действительно странно, что ==не поддерживается. Во всяком случае, спасибо за ответ i.ID.Equals(someId)отлично работает для меня.
mykhailovskyi 22.07.2015 10:49:00