3

我知道 IDENTITY 字段,但我有一种感觉,我无法使用一个来解决我的问题。

假设我有多个客户。每个客户都有多个订单。每个客户都需要为他们的订单按顺序编号,具体到他们自己。

示例表结构:

Orders:
OrderID | ClientID | ClientOrderID | etc...

此表的一些示例行将是:

OrderID | ClientID | ClientOrderID | etc...
1 | 1 | 1 | ...
2 | 1 | 2 | ...
3 | 2 | 1 | ...
4 | 3 | 1 | ...
5 | 1 | 3 | ...
6 | 2 | 2 | ...

我知道天真的方法是将 MAX ClientOrderID 用于任何客户端并将该值用于 INSERT,但这会受到并发问题的影响。我正在考虑使用事务,但我不太确定可用于此的最广泛的隔离范围。我将使用 LINQ to SQL,但我觉得这无关紧要。

4

4 回答 4

2

如果我错了,有人纠正我,但只要您的 MAX() 调用与您的插入在同一步骤中,您就不会有并发问题。

所以,你不能

select @newOrderID=max(ClientOrderID) + 1
from orders
where clientid=@myClientID;

insert into ( ClientID, ClientOrderID, ...)
values( @myClientID, @newOrderID, ...);

但你可以

insert into ( ClientID, ClientOrderID, ...)
select @myClientID, max(ClientOrderID) + 1, ...
from orders
where clientid=@myClientID;

我假设 OrderID 是一个标识列。

再次,如果我在这方面不正确,请告诉我。最好有网址

于 2009-03-23T22:18:57.877 回答
1

您可以使用存储库模式来处理您的订单,并让它控制每个特定客户订单号的数量。如果您正确实施 OrderRepository,它可以在将订单保存到数据库之前控制并发和编号(让存储库而不是数据库设置编号)。

存储库模式:http ://martinfowler.com/eaaCatalog/repository.html

于 2009-03-23T22:01:28.247 回答
1

一种可能性(尽管我不喜欢这样做)是有一个查找表,它会告诉您为每个供应商提供的最大订单号。在事务内部,您将从 VendorOrderNumber 获取最新的订单,保存新订单,增加 VendorOrderNumber 中的值,提交事务。

于 2009-03-23T22:03:40.253 回答
1

这是一种奇怪的数据存储方式,但假设您需要它,则没有可以使用的内置内容。

您对 Max(ClientOrderID) 的建议很简单,而且很容易实施(遵循 John MacIntyre 的建议)。它在有几千个订单的桌子上可能会很好地工作。随着表的增长,这种方法当然会变慢。

Nick DeVore 的查找表建议实施起来有点麻烦,但不会受到数据增长的实质性影响。

根据您实际需要 ClientOrderID 的位置/时间,您可以在需要时计算 id,如下所示:

SELECT *,
ROW_NUMBER() OVER(ORDER BY OrderID) AS ClientOrderID
FROM Orders
WHERE ClientID = 1

这假定 ClientOrderID 与 OrderID 的顺序相同。如果不实际保留 ID,将其用作其他任何内容的键是很尴尬的。这种方法不应受到数据增长的影响。

于 2009-03-23T22:33:15.580 回答