Pregunta

Estoy usando un enfoque similar a otros para mantener mis objetos LINQ en mi proveedor de datos LINQ y devolver un IQueryable para permitir el filtrado, etc. Esto funciona bien para filtrar un objeto simple por su ID u otra propiedad, pero estoy teniendo un problema con un objeto de tabla de combinación que está compuesto de otros objetos secundarios

    //CoreDBDataContext db = coreDB;
public IQueryable<DTO.Position> GetPositions()    {
     return from p in coreDB.Positions
         select new DTO.Position
             {
             DTO.User = new DTO.User(p.User.id,p.User.username, p.User.firstName,p.User.lastName,p.User.email,p.User.isActive),
             DTO.Role = new DTO.Role(p.Role.id, p.Role.name, p.Role.isActive),
             DTO.OrgUnit = new DTO.OrgUnit(p.OrgUnit.id,p.OrgUnit.name,p.OrgUnit.isActive)
             };

El coreDB.Positions es mi objeto de posición Linq y estoy devolviendo una posición DTO que se compone de un usuario, OrgUnit y Role (la tabla subyacente es una tabla de unión con UserID, RoleID y OrgUnitID)

El problema que tengo es que cuando trato de agregar un filtro en Iqueryable recibo un error de SQL que dice que no hay traducción disponible para mi objeto DTO.User

public static IQueryable<Position> WithUserID(this IQueryable<Position> query, int userID)
    {
        return query.Where(p => p.User.ID == userID);
    }

Estoy completamente perdido en cuanto a cómo resolver esto, ya que todos mis resultados de Google parecen estar con personas que trabajan directamente con los objetos LINQ generados

¿Alguna idea de cómo hacer que esto funcione, o estoy haciendo algo completamente mal aquí?

Gracias

¿Fue útil?

Solución 3

Terminé sin usar filtros para mis consultas complejas. En cambio, agregué métodos al repositorio para los requisitos de consulta más complejos. Creo que esto hará que el sistema sea más fácil de entender y, por lo tanto, de mantener.

Otros consejos

He podido trabajar con éxito con un enfoque similar:

var courses = from c in Map(origCourses)
where !expiredStatuses.Contains(c.Status)
select c;

Donde el mapa tiene:

    select new UserCourseListItem
    {
        CourseID = c.CourseID,
        CourseName = cm.CourseName,
        CourseType = c.CourseType.Value
        ...

¿Qué tal probarlo con ese tipo de inicialización (en lugar de constructores)?

Ps. esto es parte de una aplicación que funciona, y expiredStatuses incluso está relacionado con una expresión compleja.

Actualización 1: Esto es similar en comparación con el escenario mencionado, porque:

  • El mapa devuelve un IQueryable, que es un objeto POCO.
  • Después de llamar al método Map que devuelve un IQueryable con el objeto POCO, estoy aplicando un filtro contra él.

Linq2SQL solo comprende los objetos generados por el diseñador. Bueno, eso no es del todo cierto, pero lo suficientemente cerca.

Entonces, cuando escribe consultas Linq contra objetos Linq2SQL, la consulta se convertirá a SQL válido cuando la consulta se ejecute realmente, no cuando se escriba. Como sus objetos DTO no son objetos Linq2SQL, Linq2SQL no sabrá cómo crear el SQL adecuado.

Si desea mantener su separación de esta manera, debe encontrar una manera de ejecutar sus consultas con solo los objetos Linq2SQL involucrados y solo asignar el resultado a sus DTO.

Tal vez podría reescribir su método de consulta para:

  

Actualización: el parámetro debe ser de tipo   Expression<>, y no hay necesidad de   devolver un IQueryable<>. Gracias a   Freddy por señalar.

public IEnumerable<DTO.Position> FindPositions(Expression<Func<Position, bool>> criteria)
{
    return from p in coreDB.Positions
           where criteria.Invoke(p)
           select new DTO.Position
                      {
                          User = new DTO.User(p.User.id, p.User.username, p.User.firstName, p.User.lastName,
                                       p.User.email, p.User.isActive),
                          Role = new DTO.Role(p.Role.id, p.Role.name, p.Role.isActive),
                          OrgUnit = new DTO.OrgUnit(p.OrgUnit.id, p.OrgUnit.name, p.OrgUnit.isActive)
                      };
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top