Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/298.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何在Linq查询中找到产品编号x订购最多的城市?_C#_Sql_Linq - Fatal编程技术网

C# 如何在Linq查询中找到产品编号x订购最多的城市?

C# 如何在Linq查询中找到产品编号x订购最多的城市?,c#,sql,linq,C#,Sql,Linq,我的班级结构如下 public class Users { public int Id { get; set; } public string Name { get; set; } public string Surname { get; set; } public int CityId { get; set; } } public class Order { public int Id { get; set; } public int UserI

我的班级结构如下

public class Users
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string Surname { get; set; }
    public int CityId { get; set; }
}
public class Order
{
    public int Id { get; set; }
    public int UserId { get; set; }
}

public class OrderDetail
{
    public int Id { get; set; }
    public int OrderId { get; set; }
    public int ProductId { get; set; }
    public int Amount { get; set; }
}
select * from
(select u.CityId, sum(od.Amount),
        ROW_NUMBER() over(order by sum(od.Amount) desc) as rn
    from Order o
        inner join OrderDetail od on o.Id = od.OrderId
        inner join Users u on u.Id = o.UserId
    where od.ProductId = x
    group by u.CityId
) 
where rn = 1;
我想作为Linq编写的查询如下:

public class Users
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string Surname { get; set; }
    public int CityId { get; set; }
}
public class Order
{
    public int Id { get; set; }
    public int UserId { get; set; }
}

public class OrderDetail
{
    public int Id { get; set; }
    public int OrderId { get; set; }
    public int ProductId { get; set; }
    public int Amount { get; set; }
}
select * from
(select u.CityId, sum(od.Amount),
        ROW_NUMBER() over(order by sum(od.Amount) desc) as rn
    from Order o
        inner join OrderDetail od on o.Id = od.OrderId
        inner join Users u on u.Id = o.UserId
    where od.ProductId = x
    group by u.CityId
) 
where rn = 1;
我试过很多东西,但都不符合结构。现在感谢您。

请尝试以下内容:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            Context db = new Context();
            int productId = 123;
            var results = (from u in db.Users
                           join o in db.Order on u.Id equals o.UserId
                           join od in db.OrderDetails.Where(x => x.ProductId == productId) on o.Id equals od.OrderId
                           select new { u = u, o = o, od = od }
                           ).GroupBy(x => x.u.CityId)
                           .Select(x => new { city = x.Key, sum = x.Sum(y => y.od.Amount) })
                           .OrderByDescending(x => x.sum)
                           .ToList();
        }
    }
    public class Context
    {
        public List<Users> Users { get;set;}
        public List<Order> Order { get; set; }
        public List<OrderDetail> OrderDetails { get; set; }
    }
    public class Users
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public string Surname { get; set; }
        public int CityId { get; set; }
    }
    public class Order
    {
        public int Id { get; set; }
        public int UserId { get; set; }
    }

    public class OrderDetail
    {
        public int Id { get; set; }
        public int OrderId { get; set; }
        public int ProductId { get; set; }
        public int Amount { get; set; }
    }
}
使用系统;
使用System.Collections.Generic;
使用System.Linq;
使用系统文本;
命名空间控制台应用程序1
{
班级计划
{
静态void Main(字符串[]参数)
{
Context db=newcontext();
int productId=123;
var results=(从u到db.Users)
在数据库中加入o。u.Id上的顺序等于o.UserId
在db.OrderDetails中加入od,其中o.Id上的(x=>x.ProductId==ProductId)等于od.OrderId
选择新的{u=u,o=o,od=od}
).GroupBy(x=>x.u.CityId)
.Select(x=>new{city=x.Key,sum=x.sum(y=>y.od.Amount)})
.OrderByDescending(x=>x.sum)
.ToList();
}
}
公共类上下文
{
公共列表用户{get;set;}
公共列表顺序{get;set;}
公共列表OrderDetails{get;set;}
}
公共类用户
{
公共int Id{get;set;}
公共字符串名称{get;set;}
公共字符串姓氏{get;set;}
public int CityId{get;set;}
}
公共阶级秩序
{
公共int Id{get;set;}
public int UserId{get;set;}
}
公共类OrderDetail
{
公共int Id{get;set;}
公共int-OrderId{get;set;}
public int ProductId{get;set;}
公共整数金额{get;set;}
}
}

显然,您有一个表
Cities
用户具有一对多关系
:每个城市都有零个或多个用户,每个用户只居住在一个城市,即外键
用户.CityId
所指的城市

类似地,在
用户
订单
之间存在一对多关系:每个用户下了零个或多个订单,每个订单都是由一个用户下的,即外键
Order.UserId
所指的用户

另外两种一对多关系:
订单
订单详细信息
产品
订单详细信息
:每个产品都是零个或多个订单数据项下的产品。每个OrderDetail都只涉及一个产品,即外键ProductId所指的产品

如何在Linq查询中找到产品编号x订购最多的城市

您对用户、订单、订单详细信息不感兴趣,甚至对所有产品都不感兴趣,只对产品X感兴趣。您想要的是该产品X订购最多的城市

为此,您需要内部联接Cities-Users-Orders-OrderDetails,并只保留[City;OrderDetail.Amount;Product.Id]的组合

删除所有与“产品编号X”无关的组合。其余的组合都是关于Product X.GroupBy City的,并将该城市的所有OrderDetails的所有金额相加

按总和降序排列,保留第一个

我的天,这将是一个大林肯!幸运的是,这并不难

首先,我们进行内部联接以生成组合[City、User、Order、OrderDetails],并且只保留所需的属性:[City、Amount、ProductId]

var productNumberX = ...;
var result = dbContext.Cities.Join(dbContext.Users,   // inner join Cities and Users
city => city.Id,                               // from every city take the primary key
user => user.CityId,                           // from every user take the foreign key

(city, user) => new                            // when they match, make one new
{
    City = city,
    UserId = user.Id,                     // for the next join we only need the UserId
})
通过第二次连接继续LINQ:通过订单连接:

.Join(dbContext.Orders,
previousJoinResult => previousJoinResult.UserId,  // from previous join take the UserId
order => order.UserId,                            // from the Order take the UserId

(previousJoinResult, order) => new                // when they match, make one new
{
    City = previousJoinResult.City,
    OrderId = order.Id,                  // for the next Join we only need the OrderId
})
第三次加入:加入OrderDetails。记住amount和ProductId

.Join(dbContext.OrderDetails,
previousJoinResult => previousJoinResult.OrderId,   // get the OrderId from previous join
orderDetail => orderDetail.OrderId,                 // get foreign key OrderId

(previousJoinResult, orderDetail) => new
{
    City = previousJoinResult.City,
    Amount = orderDetail.Amount,
    ProductId = orderDetail.ProductId,
})
仅保留关于“产品编号X”的[City、Amount、ProductId]组合:

现在我们有了所有productNumberX的组合[City,Amount,ProductId]。 把同一个城市分成几组。使用

所以:
关键选民:同一城市的群体
ElementSelector:仅显示所有joinresult组合的数量
结果选择器:每个城市及其金额之和

我们不需要ProductId,它们都是一样的

.GroupBy(joinResult => joinResult.City,

// elementSelector: keep only the Amount of the JoinResult
joinResult => joinResult.Amount,

// parameter resultSelector: for every City, and all Amounts of orderDetails of Orders
// that were placed by Users in this City, make one new
// containing the City and the sum of the amounts
(city, amountsInThisCity) => new
{
    City = city,
    TotalAmount = amountsInThisCity.Sum(),
})
因此,对于每个城市,至少有一个用户下了一个订单,订单上有关于产品X的OrderDetail,您现在有了该城市所有用户的所有订单中产品X的所有OrderDetails的金额之和

按TotalAmount降序排序,并取第一个:

.OrderByDescending(city => city.TotalAmount)
.FirstOrDefault();
结果:

产品编号x订购最多的城市,如果没有人订购过产品编号x,则为空


注意,他们的查询具有
其中rn=1
,因此他们只获取金额最高的订单。您是否使用实体框架?是否具有类似
用户.订单
的导航属性?如果没有,创建它们。