简体   繁体   中英

How do I overwrite a foreign key column in Entity Framework Core 6?

I am using Entity Framework Core 6. I have 3 tables, order , orderitem and product in SQL Server.

Primary key of order table is id , foreign keys in orderitem are orderid and product_id . Everything is set up correctly, however, the query that EF Core 6 generated is not using product_id , but keeps on using productId as the foreign key to map to the product table. Where is the best place to overwrite that?

Here is the error part:

FROM [ShipEngineOrderItems] AS [s0]   
LEFT JOIN [Products] AS [p] ON [s0].[ProductId] = [p].[Id]

This is the full error message, the select statement above it uses the correct column name

Microsoft.EntityFrameworkCore.Database.Command[20102]
Failed executing DbCommand (90ms) [Parameters=[@__orderId_0='?' (DbType = Int32)], CommandType='Text', CommandTimeout='30']
SELECT [s].[id], [s].[order_date], [t].[PId], [t].[ProductName], [t].[Price], [t].[id], [t].[Id0]
FROM [ShipEngineOrders] AS [s]
LEFT JOIN (
SELECT [s0].[product_id] AS [PId], [p].[WarehouseSku] AS [ProductName], [s0].[price] AS [Price], [s0].[id], [p].[Id] AS [Id0], [s0].[orderId]
FROM [ShipEngineOrderItems] AS [s0]
LEFT JOIN [Products] AS [p] ON [s0].[ProductId] = [p].[Id]
) AS [t] ON [s].[id] = [t].[orderId]
WHERE [s].[id] = @__orderId_0
ORDER BY [s].[id], [t].[id]

fail: Microsoft.EntityFrameworkCore.Query[10100]

An exception occurred while iterating over the results of a query for context type 'Core.Data.ApplicationDbContext'.
Microsoft.Data.SqlClient.SqlException (0x80131904): Invalid column name 'ProductId'.

Here is my code:

public partial class Order
{
    public int id { get; set; }
    public DateTime order_date { get; set; }
    public virtual ICollection<OrderItem> OrderItems { get; set; }
}

public partial class OrderItem
{
    public int id { get; set; }
    [Column(TypeName = "decimal(18,2")]
    public decimal price { get; set; }
    public int orderId { get; set; } // navigation property
    public virtual Order Order { get; set; }
    [Column("product_id")]
    public int product_id { get; set; } // navigation property
    public virtual Product Product { get; set; }
}

public partial class Product
{
   public int Id { get; set; }
   public string? WarehouseSku { get; set; } 
}

public class ApplicationDbContext : DbContext
{
    public ApplicationDbContext() { }
    public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options) : 
    base(options) { }

    public virtual DbSet<Order> Order { get; set; }
    public virtual DbSet<OrderItem> OrderItem { get; set; }
    public virtual DbSet<Product> Product { get; set; }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Order>()
           .ToTable("ShipEngineOrders", t => t.ExcludeFromMigrations());

        //modelBuilder.Entity<OrderItem>()
        //    .Property(i => i.product_id).HasColumnName("product_id");

        modelBuilder.Entity<OrderItem>()
           .ToTable("ShipEngineOrderItems", t => t.ExcludeFromMigrations());
        
        modelBuilder.Entity<Product>()
            .ToTable("Products", t => t.ExcludeFromMigrations());
    }
}

Thank you so much for your advise

Use Fluent API for reference. Add these 2 references

using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;


public partial class OrderItem
{
    public int id { get; set; }
    [Column(TypeName = "decimal(18,2")]
    public decimal price { get; set; }
    [ForeignKey("Order")] // add foreign key reference here
    public int orderId { get; set; } // navigation property
    public virtual Order Order { get; set; }
    [Column("product_id")]
    [ForeignKey("Product")] //This is the foreign key reference
    public int product_id { get; set; } // navigation property
    public virtual Product Product { get; set; }
    public virtual Order Order{ get; set; }
}

In addition, try to practise convention over configuration. If your database design is using ProductId instead of product_id. The foreign key configuration is setup automatically.This applies the same to OrderId instead of orderId

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM