跨多对多的 LINQ 语法

发布于 2024-10-31 19:57:34 字数 615 浏览 1 评论 0原文

我在 LINQ 上遇到了一些困难,正在寻求帮助。我可以在 SQL 中做到这一点,但似乎无法弄清楚如何在 LINQ 中做到这一点。 我有一个 SQL Compact 4.0 数据库,并使用 C# 对其进行建模的 Entity Framework 4.0 EDMX。

这是场景,这些表:
客户 - OrderDetails - 订单

OrderDetails 表是一个非有效负载表,只是方便多对多连接。

如果给我一个 CustomerId 编号作为参数,我想返回一个 IEnumerable

在 SQL 中我会这样写:

SELECT     Orders.*  
FROM         OrderDetails INNER JOIN  
                  Orders ON OrderDetails.OrderId = Orders.OrderId INNER JOIN  
                  Customers ON OrderDetails.CustomerId = Customers.CustomerId

How can I do this in LINQ?

I've been struggling with LINQ a bit, and was after help. I could do it in SQL, but can't seem to work out how to in LINQ.
I have a SQL Compact 4.0 Database, with a Entity Framework 4.0 EDMX modelling it, in C#.

This is the scenario, these tables:
Customers - OrderDetails - Orders

The OrderDetails table is a non-payload table, just facilitating the many to many join.

If I'm given an CustomerId Number as a parameter, I want to return an IEnumerable<Orders>.

In SQL I would've written this as:

SELECT     Orders.*  
FROM         OrderDetails INNER JOIN  
                  Orders ON OrderDetails.OrderId = Orders.OrderId INNER JOIN  
                  Customers ON OrderDetails.CustomerId = Customers.CustomerId

How can I do this in LINQ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

怂人 2024-11-07 19:57:34

如果您想“用 SQL 思考”,您可以将其作为查询表达式来执行,如下所示:

int customerId = ...;
var query = from detail in OrderDetails
            where detail.CustomerId == customerId
            join order in Orders on detail.OrderId equals order.OrderId
            select order;

请注意,这实际上根本不触及 Customers 表...我假设有足够的关系约束来确保OrderDetails.CustomerId确实指的是真实的客户。

但是,如果您已正确设置所有关系,则可以使用 Sjoerd 的答案之类的内容。请注意,这将首先获取 Customer 实体,而上面的查询则不会。不过,这是一种更加面向对象的思考方式。

编辑:看来您的关系已正确设置,有两个选项:

// This will involve checking the customer data first
var customer = db.Customers.SingleOrDefault(c => c.CustomerId == customerId);
if (customer != null)
{
    var orders = customer.Orders;
}

// This shouldn't... hopefully :) You'll end up with an empty sequence if
// the customer doesn't exist
var orders = db.Customers.Where(c => c.CustomerId == customerId)
                         .SelectMany(c => c.Orders);

If you want to "think in SQL", you can do this as a query expression like this:

int customerId = ...;
var query = from detail in OrderDetails
            where detail.CustomerId == customerId
            join order in Orders on detail.OrderId equals order.OrderId
            select order;

Note that this doesn't actually touch the Customers table at all... I'm assuming that there are enough relational constraints to ensure that OrderDetails.CustomerId really does refer to a real customer.

If you have all the relationships set up appropriately, however, you can use something like Sjoerd's answer. Note that that will first fetch the Customer entity, whereas the above query doesn't. It's a more OO way of thinking about things though.

EDIT: As it appears your relationships are set up appropriately, two options:

// This will involve checking the customer data first
var customer = db.Customers.SingleOrDefault(c => c.CustomerId == customerId);
if (customer != null)
{
    var orders = customer.Orders;
}

// This shouldn't... hopefully :) You'll end up with an empty sequence if
// the customer doesn't exist
var orders = db.Customers.Where(c => c.CustomerId == customerId)
                         .SelectMany(c => c.Orders);
十年不长 2024-11-07 19:57:34

像这样的东西:

Customer customer = DataContext.Customers.Single(c => c.Id == CustomerId);
IEnumberable<Order> orders = customer.OrderDetails.Orders;

Something like this:

Customer customer = DataContext.Customers.Single(c => c.Id == CustomerId);
IEnumberable<Order> orders = customer.OrderDetails.Orders;
长亭外,古道边 2024-11-07 19:57:34

我认为这可行:

int customerId = ...;
var query = Customers.Include("Orders").Where(cust => cust.CustomerID == customerId)

I think this could work :

int customerId = ...;
var query = Customers.Include("Orders").Where(cust => cust.CustomerID == customerId)
Hello爱情风 2024-11-07 19:57:34

如果您想要所有订单至少有一个 ID 为 customerId 的客户,您也可以尝试以下操作:

var orders = context.Orders
    .Where(o => o.Customers.Any(c => c.CustomerId == customerId)).ToList();

一个订单可以有多个客户,这对我来说有点奇怪,但这就是我对您的描述的理解:“客户- OrderDetails - Orders ... OrderDetails 表是一个非有效负载表,只是促进多对多连接。”

我期望 EntityModel 中的 Order 具有 Customers 的导航集合,而 OrderDetails 只是一个内部联接表,不作为实体存在。

If you want all orders which have at least one customer with ID customerId you could also try this:

var orders = context.Orders
    .Where(o => o.Customers.Any(c => c.CustomerId == customerId)).ToList();

It looks somewhat weird to me that one order can have many customers but that's how I understand your description: "Customers - OrderDetails - Orders ... The OrderDetails table is a non-payload table, just facilitating the many to many join."

I'm expecting that an Order in your EntityModel has a navigation collection of Customers and OrderDetails is only a internal join table not existing as an entity.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文