加入Linq查询不起作用
现在,我必须通过对客户进行分组来总结结果 我提出了一个问题,但根本不起作用。有人能帮我吗?我的问题是:加入Linq查询不起作用,linq,entity-framework,c#-4.0,linq-to-entities,Linq,Entity Framework,C# 4.0,Linq To Entities,现在,我必须通过对客户进行分组来总结结果 我提出了一个问题,但根本不起作用。有人能帮我吗?我的问题是: ![var query=from p in context.Delivery join o in (from o1 in context.OrderTables select o1) on p.OrderID equals o.OrderID into go from po in go.De
![var query=from p in context.Delivery
join o in
(from o1 in context.OrderTables select o1)
on p.OrderID equals o.OrderID
into go from po in go.DefaultIfEmpty()
join d in (from d1 in context.Diagram select d1)
on po.DiagramID equals d.DiagramID into gd
from pd in gd.Distinct()
group pd by pd.CustomerID into groupCustomer
join cu in context.CustomerCompanyTables
on groupCustomer.Key equals cu.CustomerID
select new { cu.CompanyName, SumNoTax = p.Sum(t => t.OrderID!=0 ? p.Price:d.Price)};][2]
正如我在评论中指出的,您的查询似乎过于复杂:
- 使用
而不仅仅是:… join x in (from z in context.Xx select z) on …
… join x in context.Xx on …
- 检查不存在的数据(
):表单 您使用的go.DefaultIfEmpty()
中的一个是内部联接:将返回数据 仅当条件的两侧都存在匹配对象时join
中,选择子句,而不是分组依据的结果
当然,PdtDeliveryTable
中也没有SellingPrice
在最后的select
子句中使用
我处理此类查询的方法是以增量方式构建内容,
确保我了解我在每一步中所做的事情
因此,第一步是进行连接。为此,我定义了
一个稍微简单一些的结构,可以让事情保持清晰(参见
答案的底部是定义)和一些测试数据。我正在使用
LINQ对象,但LINQ运算符的语法和语义
也是一样的(这样可以节省创建更复杂的项目和数据库的时间)
客户有多个订单,每个订单都有一个Sku(库存控制
单位a产品)。订单可以选择性地覆盖默认价格
sku(因此使用可为空的
)。还有一些
测试数据
第一步是检查我是否正确连接,然后检查
我正在处理价格凌驾:
var ctx = GetTestData();
var query = from c in ctx.Customers
join o in ctx.Orders on c.CustomerId equals o.CustomerId
join s in ctx.Skus on o.SkuId equals s.SkuId
select new { Customer = c, Order = o, Sku = s };
Console.WriteLine("CustId\tCust\t\tOrder\tSku\tPaid");
foreach (var v in query) {
Console.WriteLine("{0}\t{1}\t{2}\t{3}\t{4}",
v.Customer.CustomerId,
v.Customer.Name,
v.Order.OrderId,
v.Sku.SkuId,
v.Order.SpecificPrice ?? v.Sku.DefaultPrice);
}
导致
CustId Cust Order Sku Paid
1 Acme Corp 1 1 10.0
1 Acme Corp 2 2 15.0
1 Acme Corp 3 3 30.0
2 Beta Corp 4 1 9.99
在使用上述术语时,键的类型为客户ID的类型
,以及
AnonOfRow
是第一种类型的joines
选择
子句
这可以通过双循环显示:
- 每个不同组上的外部(使用相同的键)
- 每组中每个对象的内部(由第一个
select创建
第条)
因此:
给出:
Customer
Order Sku Price
1: Acme Corp
1 1 10.0
2 2 15.0
3 3 30.0
2: Beta Corp
4 1 9.99
在这种情况下,聚合将列表列表更改为(平面)
列表,因此只需要一个循环即可查看所有数据。使用
总和内的null检查意味着不存在null:
Cust Name Total
1 Acme Corp 55.0
2 Beta Corp 9.99
客户名称总计
1 Acme公司55.0
2贝塔公司9.99
这对于输入数据来说显然是正确的
您的解决方案应该只是替换您的类型,添加第四个
作为一个额外的连接,并根据稍微不同的类型进行调整
class客户{
公共int客户ID;
公共字符串名称;
}
类别Sku{
公鸡;
公共价格;
}
阶级秩序{
公共内部订单ID;
公共int客户ID;
公鸡;
公共价格;
}
类上下文{
公开名单客户;
公共清单SKU;
公开名单命令;
}
静态上下文GetTestData(){
var客户=新列表{
新客户{CustomerId=1,Name=“Acme Corp”},
新客户{CustomerId=2,Name=“Beta Corp”},
新客户{CustomerId=3,Name=“Gamma Corp”}
};
var skus=新列表{
新Sku{SkuId=1,DefaultPrice=10.0m},
新Sku{SkuId=2,DefaultPrice=20.0m},
新Sku{SkuId=3,DefaultPrice=30.0m}
};
var orders=新列表{
新订单{OrderId=1,CustomerId=1,SkuId=1},
新订单{OrderId=2,CustomerId=1,SkuId=2,SpecificPrice=15.0m},
新订单{OrderId=3,CustomerId=1,SkuId=3},
新订单{OrderId=4,CustomerId=2,SkuId=1,SpecificPrice=99m}
};
返回新上下文{
客户=客户,
SKU=SKU,
订单=订单
};
}
请详细说明它是如何工作的。给定一些数据,你得到的是什么与你期望得到的是什么?@Richard,错误可以在屏幕截图中看到。不,那是错误所在,而不是错误(可能有很多错误)。将错误文本添加到Q中。@Richard,我无法最终获得order表和pdtdelivery表的值。这不是编译器错误:剪切并粘贴(编辑以匹配引用的代码)编译器输出。(该查询似乎直截了当地说它是不连贯的,有很多多余的内容:例如,为什么要加入子查询而不是直接加入DbSet
)
Console.WriteLine("Customer");
Console.WriteLine("\tOrder\tSku\tPrice");
foreach (var grp in query) {
Console.WriteLine("{0}: {1}", grp.Key, grp.First().Customer.Name);
foreach (var row in grp) {
Console.WriteLine("\t{0}\t{1}\t{2}",
row.Order.OrderId,
row.Sku.SkuId,
row.Order.SpecificPrice ?? row.Sku.DefaultPrice);
}
}
Customer
Order Sku Price
1: Acme Corp
1 1 10.0
2 2 15.0
3 3 30.0
2: Beta Corp
4 1 9.99
var query = from c in ctx.Customers
join o in ctx.Orders on c.CustomerId equals o.CustomerId
join s in ctx.Skus on o.SkuId equals s.SkuId
select new { Customer = c, Order = o, Sku = s } into joinRes
group joinRes by joinRes.Customer.CustomerId into g
select new {
CustomerId = g.Key,
CustomerName = g.First().Customer.Name,
TotalPrice = g.Sum(r => r.Order.SpecificPrice ?? r.Sku.DefaultPrice)
};
Console.WriteLine("Cust\tName\t\tTotal");
foreach (var row in query) {
Console.WriteLine("{0}\t{1}\t{2}", row.CustomerId, row.CustomerName, row.TotalPrice);
}
Cust Name Total
1 Acme Corp 55.0
2 Beta Corp 9.99
class Customer {
public int CustomerId;
public string Name;
}
class Sku {
public int SkuId;
public decimal DefaultPrice;
}
class Order {
public int OrderId;
public int CustomerId;
public int SkuId;
public decimal? SpecificPrice;
}
class Context {
public List<Customer> Customers;
public List<Sku> Skus;
public List<Order> Orders;
}
static Context GetTestData() {
var customers = new List<Customer> {
new Customer { CustomerId = 1, Name = "Acme Corp" },
new Customer { CustomerId = 2, Name = "Beta Corp" },
new Customer { CustomerId = 3, Name = "Gamma Corp" }
};
var skus = new List<Sku> {
new Sku { SkuId = 1, DefaultPrice = 10.0m },
new Sku { SkuId = 2, DefaultPrice = 20.0m },
new Sku { SkuId = 3, DefaultPrice = 30.0m }
};
var orders = new List<Order> {
new Order { OrderId = 1, CustomerId = 1, SkuId = 1 },
new Order { OrderId = 2, CustomerId = 1, SkuId = 2, SpecificPrice = 15.0m },
new Order { OrderId = 3, CustomerId = 1, SkuId = 3 },
new Order { OrderId = 4, CustomerId = 2, SkuId = 1, SpecificPrice = 9.99m }
};
return new Context {
Customers = customers,
Skus = skus,
Orders = orders
};
}