【发布时间】:2017-08-23 04:30:57
【问题描述】:
我正在尝试用Linq 做一个非常简单的任务,但已经卡住了。这真的很可怕,但我想,最好知道使用这篇文章。我有两张桌子。一个是Products,另一个是Ratings。这是演示脚本:
CREATE TABLE [dbo].[Products](
[ProductID] [int] IDENTITY(1,1) PRIMARY KEY,
[ProductName] [varchar](40) NULL,
[Price] [float] NULL,
[Details] [varchar](max) NULL,
[CategoryID] [int] NULL
)
INSERT [dbo].[Products] ([ProductID], [ProductName], [Price], [Details], [CategoryID]) VALUES (1, N'Denim', 1200, NULL, 1)
INSERT [dbo].[Products] ([ProductID], [ProductName], [Price], [Details], [CategoryID]) VALUES (2, N'Denim 2', 220, NULL, 1)
INSERT [dbo].[Products] ([ProductID], [ProductName], [Price], [Details], [CategoryID]) VALUES (3, N'Pringles', 240, NULL, 2)
INSERT [dbo].[Products] ([ProductID], [ProductName], [Price], [Details], [CategoryID]) VALUES (4, N'Pringles 2', 260, NULL, 2)
INSERT [dbo].[Products] ([ProductID], [ProductName], [Price], [Details], [CategoryID]) VALUES (5, N'Pringles 3', 240, NULL, 2)
CREATE TABLE [dbo].[Ratings](
[AutoId] [int] IDENTITY(1,1) PRIMARY KEY,
[ProductId] [int] NOT NULL,
[UserRating] [float] NOT NULL
)
INSERT [dbo].[Ratings] ([AutoId], [ProductId], [UserRating]) VALUES (4, 2, 1.5)
INSERT [dbo].[Ratings] ([AutoId], [ProductId], [UserRating]) VALUES (5, 4, 2.5)
INSERT [dbo].[Ratings] ([AutoId], [ProductId], [UserRating]) VALUES (6, 1, 5)
INSERT [dbo].[Ratings] ([AutoId], [ProductId], [UserRating]) VALUES (7, 2, 2.5)
输出应该如下:
ProductId - ProductName - User Rating
1 - Denim - 5
2 - Denim 2 - 2
3 - Pringles - 0
4 - Pringles 2 - 2.5
5 - Pringles 3 - 0
这是一个项目的评级系统,我正在尝试使用Linq 获得上述输出。使用下面的Sql,我得到了结果:
SELECT m.ProductId, m.ProductName, ISNULL(SUM(k.UserRating) / COUNT(k.ProductId), 0) AS 'User Rating' FROM Products m
LEFT JOIN Ratings k ON k.ProductId = m.ProductID
GROUP BY m.ProductID, m.ProductName
不幸的是,使用以下Linq,我只能获得Ratings 表中存在的评级详细信息:
var con = (from c in db.Ratings
join d in db.Products on c.ProductId equals d.ProductID into ps
from rt in ps.DefaultIfEmpty()
group new { c, ps } by new { rt.ProductID, rt.ProductName } into g
select new ProductRating
{
ProductId = g.Key.ProductID,
ProductName = g.Key.ProductName,
Total = g.Sum(c => c.c.UserRating) / g.Count()
}).ToList();
注意:我的目标是获取 Ratings 表中不存在的评分详细信息(产品评分的总和)(如果没有数据)以及存在的评级详细信息。
更新 1 - 类 ProductRating:
public class ProductRating {
public int ProductId { get; set; }
public string ProductName { get; set; }
public double Total { get; set; } //Property for the rating
}
更新 2 - 类产品和评级:
public partial class Products
{
public int ProductID { get; set; }
public string ProductName { get; set; }
public Nullable<double> Price { get; set; }
public string Details { get; set; }
public Nullable<int> CategoryID { get; set; }
public ICollection<Ratings> Rating { get; set; }
}
public partial class Ratings
{
public int AutoId { get; set; }
public int ProductId { get; set; }
public double UserRating { get; set; }
}
使用以下Linq 查询并收到此错误 - LINQ to Entities 不支持指定的类型成员“评级”。仅支持初始化器、实体成员和实体导航属性:
var con = db.Products.Select(c => new ProductRating
{
ProductId = c.ProductID,
ProductName = c.ProductName,
Total = c.Rating.Average(d => (double?)d.UserRating) ?? 0
}).ToList();
更新 3:现在出现此错误 - 错误 2016:为条件指定的值与成员的类型不兼容,这就是我尝试的方式导航属性:
【问题讨论】:
-
您在 LINQ 查询中弄乱了左外连接的左右部分。你没有导航属性,比如
Product类中的public ICollection<Rating> Ratings { get; set; }吗?什么是使用的 ORM - 例如LINQ to SQL、EF6、EF Core 还是? -
我使用的是 EF 6.0,它有一个名为
Total的属性。在帖子中更新。
标签: linq sql-server-2008 asp.net-mvc-5