0

I am trying to get EF6 Fluent Mappings to work for my current project. I have the following Order mapping:

public class OrderMap : EntityTypeConfiguration<Order>
{
    public OrderMap()
    {
        this.ToTable("OE_Orders");
        this.Property(o => o.BillToAddress.Address1).HasColumnName("BillToAddress1");
        this.Property(o => o.BillToAddress.Address2).HasColumnName("BillToAddress2");
        this.Property(o => o.BillToAddress.City).HasColumnName("BillToCity");
        this.Property(o => o.BillToAddress.State).HasColumnName("BillToState");
        this.Property(o => o.BillToAddress.Zip).HasColumnName("BillToZip");
        this.Property(o => o.ShipToAddress.Address1).HasColumnName("ShipToAddress1");
        this.Property(o => o.ShipToAddress.Address2).HasColumnName("ShipToAddress2");
        this.Property(o => o.ShipToAddress.City).HasColumnName("ShipToCity");
        this.Property(o => o.ShipToAddress.State).HasColumnName("ShipToState");
        this.Property(o => o.ShipToAddress.Zip).HasColumnName("ShipToZip");
        this.Property(o => o.Stop).HasColumnName("RouteStopNumber");

        this.HasKey(o => o.OrderNumber).HasMany(o => o.OrderLines).WithRequired(ol => ol.Order).HasForeignKey(ol => ol.OrderNumber);
        this.HasKey(o => o.CustomerKey).HasRequired(o => o.Customer).WithRequiredDependent();
    }
}

For some reason, this tries to map CustomerKey to the OrderLines instead of the OrderNumber. I have no idea why. I can include the OrderLineMap if you need it as well. The generated SQL is:

SELECT 
[Project1].[CustomerKey] AS [CustomerKey], 
[Project1].[OrderNumber] AS [OrderNumber], 
[Project1].[OrderDate] AS [OrderDate], 
[Project1].[InvoiceDate] AS [InvoiceDate], 
[Project1].[DeliveryDate] AS [DeliveryDate], 
[Project1].[ScheduledShipDate] AS [ScheduledShipDate], 
[Project1].[Origination] AS [Origination], 
[Project1].[RouteStopNumber] AS [RouteStopNumber], 
[Project1].[RouteCode] AS [RouteCode], 
[Project1].[BillToName] AS [BillToName], 
[Project1].[BillToAddress1] AS [BillToAddress1], 
[Project1].[BillToAddress2] AS [BillToAddress2], 
[Project1].[BillToCity] AS [BillToCity], 
[Project1].[BillToState] AS [BillToState], 
[Project1].[BillToZip] AS [BillToZip], 
[Project1].[ShipToName] AS [ShipToName], 
[Project1].[ShipToAddress1] AS [ShipToAddress1], 
[Project1].[ShipToAddress2] AS [ShipToAddress2], 
[Project1].[ShipToCity] AS [ShipToCity], 
[Project1].[ShipToState] AS [ShipToState], 
[Project1].[ShipToZip] AS [ShipToZip], 
[Project1].[EstimatedOrder] AS [EstimatedOrder], 
[Project1].[TotalWeight] AS [TotalWeight], 
[Project1].[CustomerKey1] AS [CustomerKey1], 
[Project1].[CustomerCode] AS [CustomerCode], 
[Project1].[Name] AS [Name], 
[Project1].[Phone1] AS [Phone1], 
[Project1].[Phone2] AS [Phone2], 
[Project1].[FAX] AS [FAX], 
[Project1].[Email] AS [Email], 
[Project1].[Website] AS [Website], 
[Project1].[Contact1] AS [Contact1], 
[Project1].[Contact2] AS [Contact2], 
[Project1].[Contact3] AS [Contact3], 
[Project1].[Address1] AS [Address1], 
[Project1].[Address2] AS [Address2], 
[Project1].[City] AS [City], 
[Project1].[State] AS [State], 
[Project1].[Zip] AS [Zip], 
[Project1].[C1] AS [C1], 
[Project1].[OrderNumber1] AS [OrderNumber1], 
[Project1].[LineType] AS [LineType], 
[Project1].[LineItem] AS [LineItem], 
[Project1].[TextFlag] AS [TextFlag], 
[Project1].[ProductKey] AS [ProductKey], 
[Project1].[UnitOfMeasure_SellBy] AS [UnitOfMeasure_SellBy], 
[Project1].[Quantity_SellBy] AS [Quantity_SellBy], 
[Project1].[UnitOfMeasure_Prc] AS [UnitOfMeasure_Prc], 
[Project1].[UnitOfMeasure_Stk] AS [UnitOfMeasure_Stk], 
[Project1].[UnitOfMeasure_Alt] AS [UnitOfMeasure_Alt], 
[Project1].[OrderQuantity] AS [OrderQuantity], 
[Project1].[Quantity_Stk] AS [Quantity_Stk], 
[Project1].[Quantity_Alt] AS [Quantity_Alt], 
[Project1].[Quantity_Prc] AS [Quantity_Prc], 
[Project1].[PriceDefault] AS [PriceDefault], 
[Project1].[PriceOverride] AS [PriceOverride], 
[Project1].[PriceFlag] AS [PriceFlag]
FROM ( SELECT 
    [Extent1].[CustomerKey] AS [CustomerKey], 
    [Extent1].[OrderNumber] AS [OrderNumber], 
    [Extent1].[OrderDate] AS [OrderDate], 
    [Extent1].[InvoiceDate] AS [InvoiceDate], 
    [Extent1].[DeliveryDate] AS [DeliveryDate], 
    [Extent1].[ScheduledShipDate] AS [ScheduledShipDate], 
    [Extent1].[Origination] AS [Origination], 
    [Extent1].[RouteStopNumber] AS [RouteStopNumber], 
    [Extent1].[RouteCode] AS [RouteCode], 
    [Extent1].[BillToName] AS [BillToName], 
    [Extent1].[BillToAddress1] AS [BillToAddress1], 
    [Extent1].[BillToAddress2] AS [BillToAddress2], 
    [Extent1].[BillToCity] AS [BillToCity], 
    [Extent1].[BillToState] AS [BillToState], 
    [Extent1].[BillToZip] AS [BillToZip], 
    [Extent1].[ShipToName] AS [ShipToName], 
    [Extent1].[ShipToAddress1] AS [ShipToAddress1], 
    [Extent1].[ShipToAddress2] AS [ShipToAddress2], 
    [Extent1].[ShipToCity] AS [ShipToCity], 
    [Extent1].[ShipToState] AS [ShipToState], 
    [Extent1].[ShipToZip] AS [ShipToZip], 
    [Extent1].[EstimatedOrder] AS [EstimatedOrder], 
    [Extent1].[TotalWeight] AS [TotalWeight], 
    [Extent2].[CustomerKey] AS [CustomerKey1], 
    [Extent2].[CustomerCode] AS [CustomerCode], 
    [Extent2].[Name] AS [Name], 
    [Extent2].[Phone1] AS [Phone1], 
    [Extent2].[Phone2] AS [Phone2], 
    [Extent2].[FAX] AS [FAX], 
    [Extent2].[Email] AS [Email], 
    [Extent2].[Website] AS [Website], 
    [Extent2].[Contact1] AS [Contact1], 
    [Extent2].[Contact2] AS [Contact2], 
    [Extent2].[Contact3] AS [Contact3], 
    [Extent2].[Address1] AS [Address1], 
    [Extent2].[Address2] AS [Address2], 
    [Extent2].[City] AS [City], 
    [Extent2].[State] AS [State], 
    [Extent2].[Zip] AS [Zip], 
    [Extent3].[OrderNumber] AS [OrderNumber1], 
    [Extent3].[LineType] AS [LineType], 
    [Extent3].[LineItem] AS [LineItem], 
    [Extent3].[TextFlag] AS [TextFlag], 
    [Extent3].[ProductKey] AS [ProductKey], 
    [Extent3].[UnitOfMeasure_SellBy] AS [UnitOfMeasure_SellBy], 
    [Extent3].[Quantity_SellBy] AS [Quantity_SellBy], 
    [Extent3].[UnitOfMeasure_Prc] AS [UnitOfMeasure_Prc], 
    [Extent3].[UnitOfMeasure_Stk] AS [UnitOfMeasure_Stk], 
    [Extent3].[UnitOfMeasure_Alt] AS [UnitOfMeasure_Alt], 
    [Extent3].[OrderQuantity] AS [OrderQuantity], 
    [Extent3].[Quantity_Stk] AS [Quantity_Stk], 
    [Extent3].[Quantity_Alt] AS [Quantity_Alt], 
    [Extent3].[Quantity_Prc] AS [Quantity_Prc], 
    [Extent3].[PriceDefault] AS [PriceDefault], 
    [Extent3].[PriceOverride] AS [PriceOverride], 
    [Extent3].[PriceFlag] AS [PriceFlag], 
    CASE WHEN ([Extent3].[OrderNumber] IS NULL) THEN CAST(NULL AS int) ELSE 1 END AS [C1]
    FROM   [dbo].[OE_Orders] AS [Extent1]
    INNER JOIN [dbo].[AR_Customers] AS [Extent2] ON [Extent1].[CustomerKey] = [Extent2].[CustomerKey]
    LEFT OUTER JOIN [dbo].[OE_OrderLines] AS [Extent3] ON [Extent1].[CustomerKey] = [Extent3].[OrderNumber]
    WHERE [Extent1].[OrderNumber] = @p__linq__0
)  AS [Project1]
ORDER BY [Project1].[CustomerKey] ASC, [Project1].[CustomerKey1] ASC, [Project1].[C1] ASC

This is the line in question:

LEFT OUTER JOIN [dbo].[OE_OrderLines] AS [Extent3] ON [Extent1].[CustomerKey] = [Extent3].[OrderNumber]

Not sure how to fix it. I could use some advice or some resources to help me figure out why it is mapping incorrectly.

Let me know how I can update this information to make it more informative.

Thank you all for your time!

Carson
  • 1,169
  • 13
  • 36
  • Is the `Order` -> `Customer` relationship really `one-to-one`? It's strange, usually one `Customer` has many `Order`s, doesn't it? – Ivan Stoev Jul 19 '16 at 16:57
  • @IvanStoev Yes, the customer has many orders but I am not mapping Customer with an Order collection. It would be too much. I can add it, but it is not necessary for this application. – Carson Jul 19 '16 at 16:58
  • It's not necessarily to have a collection. But `Has` / `With` must match the relationship cardinality. Let me ask you differently - is `Order.CustomerKey` a FK to `Customer` table? – Ivan Stoev Jul 19 '16 at 17:01
  • @IvanStoev I see what you are saying. Yes, it is a ForeignKey to the Customers table. – Carson Jul 19 '16 at 17:02

1 Answers1

2

The problem is in those two lines from the configuration:

 this.HasKey(o => o.OrderNumber).HasMany(o => o.OrderLines).WithRequired(ol => ol.Order).HasForeignKey(ol => ol.OrderNumber);
 this.HasKey(o => o.CustomerKey).HasRequired(o => o.Customer).WithRequiredDependent();

In the EF Fluent API terms, HasKey means mapping the primary key, and you have specified it twice. Since the later takes precedence (overwrites the previous setting), as a result EF maps the CustomerKey column as a PK of the Order table.

The correct configuration should be like this (I would suggest you to not mix the property, PK and association mappings):

 this.HasKey(o => o.OrderNumber);

 this.HasMany(o => o.OrderLines)
     .WithRequired(ol => ol.Order)
     .HasForeignKey(ol => ol.OrderNumber);

 this.HasRequired(o => o.Customer)
     .WithMany()
     .HasForeignKey(o => o.CustomerKey);
Ivan Stoev
  • 195,425
  • 15
  • 312
  • 343