work unit pattern genericrepository framework c# linq repository

c# - unit - LINQ, entidad que implementa la interfaz y la excepción en el mapeo



repository pattern c# entity framework 6 (4)

Estoy usando un patrón de repositorio con LINQ, tengo IRepository.DeleteOnSubmit (T Entity). Funciona bien, pero cuando mi clase de entidad tiene interfaz, así:

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 tratando de eliminar alguna entidad como esta:

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

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

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

Aquí está:
Mensaje de excepción: el miembro ''MMRI.DAL.ITag.idContent'' no tiene traducción soportada a SQL.

Código:

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

(obtiene todas las etiquetas de DB y las borra)

Y stack trace:

[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 decorar clase parcial:

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

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


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


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


Para traducir su consulta LINQ a SQL real, Linq2SQL inspecciona la expresión que le da. 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 utiliza el diseñador, también puede cambiar el nombre de la propiedad de 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 clase parcial definición para MyEntity simplemente se convierte en:

public partial class MyEntity: IEntity { }


Parece que Microsoft dejó de admitir el operador == en las interfaces cuando usaba linq-to-sql en MVC4 (o tal vez nunca fue compatible). Sin embargo, puede usar i.ID.Equals(someId) en lugar del operador == .

¡Casting IEnumerable to IQueryable funciona pero no debería ser usado! El motivo es: IQueryable tiene una implementación funky de IEnumerable . Cualquiera que sea el método de linq que use en un IQueryable través de la interfaz IEnumerable hará que la consulta se ejecute primero, IEnumerable todos los resultados obtenidos en la memoria del DB y finalmente ejecute el método localy 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 el descuido de IEnumerable a IQueryable y los datos relacionados con la carga diferida).

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