Reputation: 79
I am trying to modify a C# .NET MVC web app and existing database to implement some new functionality. However, try as i might, i cannot modify the database structure without creating a circular reference and i was hoping someone may have a solution.
I want to implement a method of order routing. So depending on thresholds set on a customer an order will be produced one of two ways depending on the order size. So i find when i design the database the customer needs to reference the routing table as it dictates when an order comes where it should go. Also because an order is attached to a route it also needs to reference the routing table which results in a circular reference:
The customers, products and order are already in production so i would be nervous about modifying those relationships if required.
Any help is greatly appreciated! Thanks in advance.
Upvotes: 0
Views: 339
Reputation: 934
By the way, you don't have a circular reference! If I understand the problem, you want to configure each customer with one of two routes (above and below threshold). Then, the order will go as per that route (order route)
First, the meaning of the foiregn key in the above three relationship is different, one determining preference, and one determining actual
Then, the actual route that the order took is the one attached to it. If you don't have a requirement of tracking history (like, how does this order took this route while the customer is constraint to one of different two?) then I see your design - for this particular question - is valid
I still don't know why the PRODUCT table is linked to customer the way it is! Maybe it is then a CUSTOMER_PRODUCT, but that's outside your question
You can get the route certain order needs to take by selecting:
select case when :thresh > threshold then aboveThresholdRoute else belowThresholdRoute end
from customer
where id = :customer_id
Where threshold is calculated based on whatever formula you have, and for the order customer
Upvotes: 1
Reputation: 9509
First of all, the schema that is already in production
does not seem extensible enough. However, your customer does NOT need to be referencing Route
. A Route
is a property of an Order
, and an Order
is a property of the Customer (via Product
association).
So you need to create a new Routes
table, like so
CREATE TABLE Routes
(Id UNIQUEIDENTIFIER,
Name NVARCHAR(50));
Then alter Order table like so:
ALTER TABLE Order ADD RouteId UNIQUEIDENTIFIER;
ALTER TABLE Order ADD CONSTRAINT FK_Routes_Id FOREIGN KEY (RouteId) REFERENCES Routes(Id);
Then, to select the Routes for the user:
SELECT * FROM Routes
INNER JOIN Order
ON
Routes.Id = Order.RouteId
INNER JOIN Product
ON
Product.LastOrder = Order.Id -- Assuming that is the FK here, not clear from the question
INNER JOIN Customers
ON
Product.CustomerId = Customers.Id
WHERE
Customers.Id = 'some value here'
UPDATE Since you now mentioned routes are user specific, rather than order specific, you can simply change it like so:
CREATE TABLE Routes
(Id UNIQUEIDENTIFIER,
Name NVARCHAR(50));
Then alter Customers table like so:
ALTER TABLE Customers ADD RouteId UNIQUEIDENTIFIER;
ALTER TABLE Customers ADD CONSTRAINT FK_Routes_Id FOREIGN KEY (RouteId) REFERENCES Routes(Id);
Then to select route for an order, do:
SELECT * FROM Routes
INNER JOIN Customers
ON
Routes.Id = Customers.RouteId
INNER JOIN Product
ON
Product.CustomerId = Customers.Id
INNER JOIN Order
ON
Product.LastOrder = Order.Id -- Assuming that is the FK here, not clear from the question
WHERE
Order.Id = 'some value here'
Upvotes: 0