Pregunta

¿Cómo puedo filtrar el IsSoftDeleted elementos de este DbSet?

var type = GetTypeFromString("Whatever");
var whatevers = Set(type);

Método

public dynamic Set(Type type)
{
    var set = dbContext.Set(type);
    return set;
}

Modelo

public class Whatever : BaseEntity
{
    public virtual string Name { get; set; }
}
public class BaseEntity
{
   public virtual int Id { get; set; }
   public virtual bool? IsSoftDeleted { get; set; }
}

EDITAR:olvidé mostrar Whatever deriva de BaseEntity

¿Fue útil?

Solución

Su clase Whatever no tiene ninguna propiedad IsSoftDeleted, por lo que no hay nada que filtrar. Voy a asumir que lo que sea que se derive de BaseEntity.

El problema principal es que IQueryable .Where realmente no existe: es un método de extensión, y los métodos de extensión no funcionan bien con los tipos dinámicos. Si el compilador puede ver que un tipo implementa IQueryable , puede escribir var.Where (...) y hacer que el compilador lo resuelva en System.Linq.Queryable.Where (var, ...). Dado que el tipo es dinámico en su ejemplo, el compilador no sabe que implementa IQueryable e informará un error cuando intente llamar a Where.

Puede convertir el DbSet a IQueryable (siempre que Type tenga BaseEntity como clase base) y llamar a cualquier filtro sobre eso. ¿Utiliza realmente la función de tipo dinámico? De lo contrario, también puede considerar eliminar su función Set personalizada y usar la función DbContext.Set predeterminada.

var query = (from e in (IQueryable<BaseEntity>)dbContext.Set(type)
             where e.IsSoftDeleted != true
             select e);

Nota: esto no es lo mismo que usar dbContext.Set (type) .Cast (): eso no funcionará, porque un DbSet y un DbSet son incompatibles. Es solo con IQueryable y otras interfaces con argumentos de tipo "out" que puede hacer esto.

Otros consejos

El problema es ese Set(Type type) devuelve un no genérico DbSet.Para aplicar tu filtro debes convertirlo en un genérico. IQueryable<T>:

var set = ((IQueryable<BaseEntity>)dbContext.Set(type))
              .Where(be => be.IsSoftDeleted.HasValue && !be.IsSoftDeleted.Value);

Esto funciona sólo si type se deriva de BaseEntity o BaseEntity en sí mismo; de lo contrario, obtendrá una excepción de tiempo de ejecución.

La resultante set es de tipo IQueryable<BaseEntity>, entonces la pregunta es qué tan útil es este resultado y cómo puede aplicar filtros adicionales para sus entidades derivadas como Where(w => w.Name == "abc").Al menos, no pude obtener código compilable haciendo set de tipo dynamic.Tampoco me gustaría perder toda la escritura fuerte.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top