【发布时间】:2019-08-03 19:11:54
【问题描述】:
我有一个 Net Core 2.2 Web 应用程序、SQL Server 2017、Linq、Entity Core、SQLQuery FromSql
我需要对电子商务网站等产品进行复杂的过滤,您可以在其中按属性过滤笔记本电脑(品牌:戴尔、惠普、内存:2 GB、4 GB)
示例:(戴尔品牌或惠普品牌)和(S 码或 XL 码)。
我在选择多个属性后尝试使用产品数量(Count)显示属性和值时遇到问题(例如:选择 2 GB 或 4 GB 后的戴尔(4 件商品))
属性/过滤器:
Brand
- Dell (2 items)
- HP (3)
Memory
- 2 GB (2)
- 4 GB(3)
Display
- 17 inch (1)
- 19 inch ( 2)
因为在 LINQ 中无法实现,所以必须使用字符串 SQLQuery FromSql 来完成
SQL 数据库结构:
**Products** ( Ex: Laptop 1, Laptop 2 )
- ProductID
**Attributes** ( Ex: Memory, Brand )
- AttributeID
**AttributeValues** ( Ex: 2 Gb, Dell )
- AttributeValueID
- AttributeID ( foreign key )
**ProductAttributes**
-ProductAttibuteID
-ProductID ( foreign key )
-AttributeID ( foreign key )
-AttributeValueID ( foreign key )
我已经尝试了一些东西,但没有工作并不算好:
public class Filter
{
public int AtributeID { get; set; }
public int ?AtributeValueID { get; set; }
}
// Filters - list with selected attributes ( AtributeID ,AtributeValueID )
string SQLQuery = "SELECT AtributeValueID,Title,Importance,AtributeID , (select count (*) from Products p where p.ProductCategoryID ={0}";
foreach (var filtersGroup in Filters.GroupBy(p => p.AtributeID))
{
int atributeID = filtersGroup.Key;
var atributeValues = filtersGroup.Select(p => p.AtributeValueID).ToList();
SQLQuery += "and exists ( select 1 from ProductAtributes pa where pa.ProductID=p.ProductID and ((av.AtributeID = " + atributeID + " and pa.AtributeValueID = av.AtributeValueID) ";
foreach (var atributeValueID in atributeValues)
{
SQLQuery += " or pa.AtributeValueID=" + atributeValueID;
}
SQLQuery += "))";
}
SQLQuery += ") as Count";
SQLQuery += " FROM AtributeValues av ";
var queryAtributesValuesResult = context.Query<AtributeValueDTO>()
.FromSql(SQLQuery)
.AsNoTracking()
.ToList();
Executed DbCommand (1,203ms)
SELECT AtributeValueID,Title,Importance,AtributeID,
(
select count (*) from Products p where
exists
(
select 1 from ProductAtributes pa where pa.ProductID=p.ProductID
and ((av.AtributeID = 15 and pa.AtributeValueID = av.AtributeValueID) or pa.AtributeValueID=130)
)
and exists
(
select 1 from ProductAtributes pa where pa.ProductID=p.ProductID
and ((av.AtributeID = 27 and pa.AtributeValueID = av.AtributeValueID) or pa.AtributeValueID=273 or pa.AtributeValueID=325)
)
)as Count
FROM AtributeValues av
【问题讨论】:
-
LINQ 非常适合动态构建复杂的条件查询。显示您的实体。
-
我使用 SQL Server 2017 。服务器位于 Azure 中。是的,上下文是实体核心框架。是的,我知道 Linq 不能在这种情况下使用,这就是为什么我们的重点是编写查询、视图或除 SQL 之外的其他内容的原因
-
问题解决了吗?如果没有,请在 C# 中显示您的实体,我将在 LINQ 中给出解决方案。
-
不,没有解决。实体与数据库结构相同:产品(例如:Laptop 1、Laptop 2)- ProductID Attributes(例如:内存、品牌)- AttributeID AttributeValues(例如:2 Gb,Dell)- AttributeValueID - AttributeID(外键) ProductAttributes -ProductAttibuteID -ProductID(外键) -AttributeID(外键) -AttributeValueID(外键)
标签: sql asp.net-core filter