2008-08-18 16 views
9

Estoy usando un patrón de repositorio con LINQ, tengo IRepository.DeleteOnSubmit (T Entity). Funciona bien, pero cuando mi clase de entidad tiene interfaz, como esto:LINQ, entidad que implementa Interfaz y excepción en el mapeo

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

public partial class MyEntity: IEntity { 

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

y luego intentar eliminar una entidad como esta:

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

tiros
El miembro IEntity.ID 'tiene no hay traducción soportada a SQL.

recuperar datos de la base de datos funciona, pero eliminar e insertar no. ¿Cómo usar la interfaz contra DataContext?


Aquí está:
mensaje Excepción: El miembro MMRI.DAL.ITag.idContent 'no tiene traducción apoyado a SQL.

Código:

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

(se pone todas las etiquetas de DB, y los borra)

y seguimiento de la pila:

[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(... 

Cuando intento hacer decorar clase parcial:

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

it arroja el error "Nombre de columna inválido 'idContent'."

+2

Desbordamiento de pila no es un foro. Algunas de las cosas que usted (y otros) publicaron como "Respuesta" a la pregunta en realidad deberían ser "comentarios". También puede editar la pregunta original y cualquier respuesta. – jeroenh

Respuesta

0

Prueba esto:

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; }  
     } 
} 
3

Esto funciona para mí -

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

Hay problemas con hacer lo anterior, lamentablemente - http://social.msdn.microsoft.com/Forums/en-US/linqtosql/thread/5691e0ad-ad67-47ea-ae2c-9432e4e4bd46 hay un enlace a una error registrado en MS Connect en la parte inferior de esa página. Espero que algunos de ustedes puedan votarlo para que lo puedan ver, es un problema que me molesta desde hace un tiempo ... –

0

Para traducir su consulta LINQ a SQL real, Linq2SQL inspecciona la expresión que le des. El problema es que no ha proporcionado suficiente información para que L2S pueda traducir la propiedad "ID" al nombre real de la columna DB. Puede lograr lo que quiere asegurándose de que L2S pueda asignar "ID" a "IDField".

Esto debería ser posible utilizando el enfoque proporcionado en las respuestas.

Si usa el diseñador, también puede cambiar el nombre de la propiedad de la clase "IDField" por "ID", con el beneficio adicional de que ya no tendrá que implementar explícitamente la propiedad "ID" en su clase parcial, es decir, la definición de la clase parcial para myEntity simplemente se convierte en:

public partial class MyEntity: IEntity 
{  
} 
7

Parece Microsoft abandonado el soporte para interfaces de operador == al utilizar LINQ a SQL en MVC4 (o tal vez nunca fue apoyado). Sin embargo, puede usar i.ID.Equals(someId) en lugar del operador ==.

Casting IQueryable a IEnumerable ¡funciona pero no se debe utilizar! La razón es: IQueryable tiene una implementación funky de IEnumerable.Cualquiera que sea el método linq que use en un IQueryable a través de la interfaz IEnumerable hará que la consulta se ejecute primero, obtenga todos los resultados obtenidos en la memoria de la base de datos y finalmente ejecute el método localmente en los datos (normalmente esos métodos se traducirán) a SQL y ejecutado en la base de datos). Imagínese tratando de obtener una sola fila de una tabla que contenga mil millones de filas, buscando todas ellas solo para elegir una (y empeora con la conversión descuidada de IQueryable a IEnumerable y datos relacionados con la carga diferida).

Aparentemente Linq no tiene ningún problema en utilizar el operador == con interfaces en datos locales (por lo que solo IQueryable se ve afectado) y también con Entity Frameworks (o eso escuché).

+0

Es realmente extraño que '==' no sea compatible. De todos modos, gracias por la respuesta 'i.ID.Equals (someId)' funciona bien para mí. – mykhailovskyi

Cuestiones relacionadas