Buscar productos de la base de datos en la base de filtros de búsqueda -- # campo con performance campo con linq-to-sql camp codereview Relacionados El problema

Search products from database on base of search filters


3
vote

problema

Español

Estoy escribiendo un código para buscar la base de datos de productos y la devolución del resultado. El usuario puede seleccionar varias opciones como los atributos del producto que varían de producto a otro, también puede haber un caso como para un atributo único puede haber un valor múltiple. Por ejemplo, el usuario puede seleccionar la marca como filtro y puede seleccionar de la marca dada en la opción de marca. Puede haber una etiqueta múltiple para filtrar como este

Por favor, guíame para mejorar este código, ¿hay algún patrón de diseño que utilice o pueda reemplazar alguna declaración con otra para mejorar en cualquier sentido?

  public Models.Custom_Model.SubcategoryProductViewModel SubCategoryAds(long subcategoryId, Models.Custom_Model.SearchModel search)     {         var products = _db.products.Include(a => a.category).Include(c => c.subcategory).Include(c=>c.productattributes).Where(c => c.SubCategoryId == subcategoryId && c.subcategory.isActive && c.category.isActive);         switch (search.criteria)         {             case Enum.SortingCriteria.New:                 products = products.OrderByDescending(c => c.ProductId);                 break;             case Enum.SortingCriteria.Discount:                 products = products.OrderByDescending(c => c.Discount);                 break;             case Enum.SortingCriteria.PricebyAsc:                 products = products.OrderBy(c => c.Price);                 break;             case Enum.SortingCriteria.PricebyDsc:                 products = products.OrderByDescending(c => c.Price);                 break;         }         if(search.filter != null)         {             var fs = search.filter.SelectMany(c => c.Value.Select(a => new Models.Custom_Model.IdName {Id = c.Id,Name = a}));             products.Where(z=>((z.productattributes.Select(c=>new Models.Custom_Model.IdName {Id = c.AttributeId,Name = c.Value})).Intersect(fs)).Any());         }         var productids = products.Skip((search.pageNo - 1) * search.pagesize).Take(search.pagesize).Select(c => c.ProductId).ToList();         var subcategory = _db.subcategories.Include(c => c.category).SingleOrDefault(c => c.SubCategoryId == subcategoryId);         string Name = string.Empty;         Models.Custom_Model.IdName category = null;         if (subcategory != null)         {             Name = subcategory.Name;             category = new Models.Custom_Model.IdName() { Id = subcategory.CategoryId, Name = subcategory.category.Name };         }         var count = products.Count();         var product = Business_Logic.ProductTile.ToproductTile(productids, _db);         return new  Models.Custom_Model.SubcategoryProductViewModel {Category = category ,Name = Name,TotalItems = count, Products = product };     }   

modelo de búsqueda

  public class SearchModel {     private int _pagesize = 50;      public int pagesize     {         get { return _pagesize; }         set { _pagesize =value; }     }      private int _pageNo = 1;      public int pageNo     {         get { return _pageNo; }         set { _pageNo = value; }     }      private Enum.SortingCriteria _criteria = Enum.SortingCriteria.New;      public Enum.SortingCriteria criteria     {         get { return _criteria; }         set { _criteria = value; }     }      private List<FiltersViewModel> _filter = null;      public List<FiltersViewModel> filter     {         get { return _filter ; }         set { _filter  = value; }     }   }   

filterviewmodel

  public class FiltersViewModel {     public long Id { get; set; }      public IEnumerable<string> Value { get; set; } }   
Original en ingles

I am writing a code to search Product database and return result to user. user can select various options like product attributes that varies from product to product, also there may be case like for single attribute there can be multiple value. For Example user can select brand as filter and can select from given brand under brand option. There can be multiple tag for filter like this

Please guide me to improve this code, is there any design pattern i should use or can replace some statement with other to improve in any Sense.

public Models.Custom_Model.SubcategoryProductViewModel SubCategoryAds(long subcategoryId, Models.Custom_Model.SearchModel search)     {         var products = _db.products.Include(a => a.category).Include(c => c.subcategory).Include(c=>c.productattributes).Where(c => c.SubCategoryId == subcategoryId && c.subcategory.isActive && c.category.isActive);         switch (search.criteria)         {             case Enum.SortingCriteria.New:                 products = products.OrderByDescending(c => c.ProductId);                 break;             case Enum.SortingCriteria.Discount:                 products = products.OrderByDescending(c => c.Discount);                 break;             case Enum.SortingCriteria.PricebyAsc:                 products = products.OrderBy(c => c.Price);                 break;             case Enum.SortingCriteria.PricebyDsc:                 products = products.OrderByDescending(c => c.Price);                 break;         }         if(search.filter != null)         {             var fs = search.filter.SelectMany(c => c.Value.Select(a => new Models.Custom_Model.IdName {Id = c.Id,Name = a}));             products.Where(z=>((z.productattributes.Select(c=>new Models.Custom_Model.IdName {Id = c.AttributeId,Name = c.Value})).Intersect(fs)).Any());         }         var productids = products.Skip((search.pageNo - 1) * search.pagesize).Take(search.pagesize).Select(c => c.ProductId).ToList();         var subcategory = _db.subcategories.Include(c => c.category).SingleOrDefault(c => c.SubCategoryId == subcategoryId);         string Name = string.Empty;         Models.Custom_Model.IdName category = null;         if (subcategory != null)         {             Name = subcategory.Name;             category = new Models.Custom_Model.IdName() { Id = subcategory.CategoryId, Name = subcategory.category.Name };         }         var count = products.Count();         var product = Business_Logic.ProductTile.ToproductTile(productids, _db);         return new  Models.Custom_Model.SubcategoryProductViewModel {Category = category ,Name = Name,TotalItems = count, Products = product };     } 

search Model

public class SearchModel {     private int _pagesize = 50;      public int pagesize     {         get { return _pagesize; }         set { _pagesize =value; }     }      private int _pageNo = 1;      public int pageNo     {         get { return _pageNo; }         set { _pageNo = value; }     }      private Enum.SortingCriteria _criteria = Enum.SortingCriteria.New;      public Enum.SortingCriteria criteria     {         get { return _criteria; }         set { _criteria = value; }     }      private List<FiltersViewModel> _filter = null;      public List<FiltersViewModel> filter     {         get { return _filter ; }         set { _filter  = value; }     }   } 

FilterViewModel

public class FiltersViewModel {     public long Id { get; set; }      public IEnumerable<string> Value { get; set; } } 
        
 
 

Lista de respuestas

0
 
vote
vote
La mejor respuesta
 

al menos un par de cosas para notar:

Bug?

Creo que esta parte no funciona porque no asigna el resultado de esta consulta de nuevo a la variable.

  if(search.filter != null) {     var fs = search.filter.SelectMany(c => c.Value.Select(a => new Models.Custom_Model.IdName {Id = c.Id,Name = a}));     products.Where(z=>((z.productattributes.Select(c=>new Models.Custom_Model.IdName {Id = c.AttributeId,Name = c.Value})).Intersect(fs)).Any()); }   

Naming

Las propiedades públicas deben estar en Pascalcasing ( MSDN ) variables privadas en camellas.

Además, algunas declaraciones de uso eliminarían el espacio de nombres-desorden.

Roturas de línea

Creo que un par de salidas de líneas harían largas líneas más legibles. Primera línea como ejemplo.

  var products = _db.products     .Include(a => a.category)     .Include(c => c.subcategory)     .Include(c => c.productattributes)     .Where(c => c.SubCategoryId == subcategoryId && c.subcategory.isActive && c.category.isActive);   

Refactorización a métodos más pequeños

Paginación (omitir y tomar x registros) es un concepto bastante general, por lo que quizás debería ser movido a su propia función genérica.

Además, la clasificación podría ser movida a su propio método

SearchModel Refactoring

Retire las variables privadas de SearchModel porque solo se usan para los valores predeterminados. Establecería los valores predeterminados en constructor, por lo que los valores predeterminados están en un solo lugar. El filtro no necesita ser establecido, pero lo configuré aquí para la consistencia.

También cambió de nombre a los criterios a los criterios de clasificación para hacer que el significado sea Clearir. Si es solo criterio, no está claro si se usa para filtrar la consulta o la clasificación.

  public int PageSize { get; set; } public int PageNumber { get; set; } public Enum.SortingCriteria SortingCriteria { get; set; } public List<FiltersViewModel> Filter { get; set; }  public SearchModel() {     PageSize = 50;     PageNumber = 1;     SortingCriteria = Enum.SortingCriteria.New;     Filter = null; }   
 

At least a couple things to note:

Bug?

I think this part doesn't work because you don't assign the result of this query back to the variable.

if(search.filter != null) {     var fs = search.filter.SelectMany(c => c.Value.Select(a => new Models.Custom_Model.IdName {Id = c.Id,Name = a}));     products.Where(z=>((z.productattributes.Select(c=>new Models.Custom_Model.IdName {Id = c.AttributeId,Name = c.Value})).Intersect(fs)).Any()); } 

Naming

Public properties should be in PascalCasing (msdn) private variables in camelCase.

Also, some using-statements would remove the namespace-clutter.

Line breaks

I think couple of line breaks would make long lines more readable. First line as an example.

var products = _db.products     .Include(a => a.category)     .Include(c => c.subcategory)     .Include(c => c.productattributes)     .Where(c => c.SubCategoryId == subcategoryId && c.subcategory.isActive && c.category.isActive); 

Refactoring to smaller methods

Pagination (skipping and taking x records) is pretty general concept, so it should perhaps be moved to to its own, generic function.

Also, sorting could be moved to its own method

SearchModel refactoring

I remove private variables from SearchModel because they are only used for defaults. I would set defaults in constructor so defaults are in one place. Filter doesn't need to be set but I set it here for consistency.

I also renamed Criteria to SortingCriteria to make the meaning clearir. If it is only Criteria, it is not clear if it is used to filter the query or sorting.

public int PageSize { get; set; } public int PageNumber { get; set; } public Enum.SortingCriteria SortingCriteria { get; set; } public List<FiltersViewModel> Filter { get; set; }  public SearchModel() {     PageSize = 50;     PageNumber = 1;     SortingCriteria = Enum.SortingCriteria.New;     Filter = null; } 
 
 

Relacionados problema

5  Eficiencia de una consulta LINQ en una estructura anidada  ( Efficiency of a linq query on a nested structure ) 
Para un sitio web de encuestas He escrito esta consulta para mostrar los resultados de la encuesta, con un porcentaje para cada respuesta elegida: getFirst...

2  Retrasado incluye reglas para entidadesTyTyPeconfiguración utilizando expresiones LINQ  ( Delayed include rules for entitytypeconfiguration using linq expressions ) 
El objetivo de esta clase es establecer reglas para incluir las propiedades de navegación en el nivel de configuración y luego aplicar donde sea necesario en ...

2  Linq C # tirando de la fila de la tabla a los campos de entrada  ( Linq c pulling from table row into input fields ) 
Hoy es la primera vez que he usado LINQ, así que quería obtener una revisión de código en esto y asegurarme de que lo voy correctamente. Estoy llenando los ...

2  ¿Cómo hacer mi código más rápido y más fácil?  ( How to make my code faster and easier ) 
Este es mi código de pieza .cs donde estoy llamando storeprocedure en Linq a SQL: var rr_j_cat = db.allcategories().ToList();//its store procedure callin...

1  Ansioso cargando profundamente en un modelo con una propiedad de colección cuyo tipo es heredado  ( Eager loading deeply into a model with a collection property whose type is inher ) 
Visual Studio generó esta gran ruta para mí, donde puedo cargar una entidad: // GET: api/Jobs/5 [ResponseType(typeof(Job))] public async Task<IHttpActionRe...

1  Agregando clientes y tipos de clientes  ( Aggregating clients and client types ) 
El código que he reunido logra lo que quiero, pero no sé si es la forma correcta de enfrentar el problema. Estoy tratando con 2 tablas (cliente, clientype) ...

3  Optimización de código mediante la eliminación de iteración constante de su estructura  ( Code optimization by constant if structure iteration removal ) 
A continuación encontrará el código específico que estoy intentando optimizar. Tengo un método anterior al llamado getCount() , basado en parámetros similare...

8  ¿Este patrón de acceso inusual de datos crea algún problema?  ( Does this unusual data access pattern create any problems ) 
el fondo Dos principiantes sin acceso a un mentor experimentado Escriba una aplicación ASP .NET MVC, en su mayoría cruda simple, utilizando Linq a SQL par...

9  Filtro de consulta LINQ a SQL, con la coincidencia de nombre Ignorando múltiples caracteres de puntuación  ( Linq to sql query filter with the name match ignoring multiple punctuation char ) 
Tengo la siguiente consulta Linq a SQL que funciona bien, pero se ve feo: var filter = "filter"; query = query.Where(x => x.Name.Replace("'", "").Repl...

7  Una forma genérica de usar LINQ a la entidad con los tipos y las operaciones desconocidas hasta el tiempo de ejecución  ( A generic way to use linq to entity with types and operations unknown until run ) 
Se solicitó una pregunta aquí Sobre la reflexión y LINQ a la entidad. Estoy tratando de modificar el código que se presentó para adaptarse a mis necesidades...




© 2022 respuesta.top Reservados todos los derechos. Centro de preguntas y respuestas reservados todos los derechos