C# EF Core无法在表中插入标识列的显式值

C# EF Core无法在表中插入标识列的显式值,c#,asp.net-core,entity-framework-core,C#,Asp.net Core,Entity Framework Core,我已经看到了,但以下错误并未消失: 当identity\u insert设置为OFF时,无法在表“Products”中为identity列插入显式值 我试过的是: [Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)] public int Id { get; set; } 此外,我还尝试设置为None: [DatabaseGenerated(DatabaseGeneratedOption.None)] public int Id

我已经看到了,但以下错误并未消失:

当identity\u insert设置为OFF时,无法在表“Products”中为identity列插入显式值

我试过的是:

[Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)] 
public int Id { get; set; }
此外,我还尝试设置为
None

[DatabaseGenerated(DatabaseGeneratedOption.None)]
public int Id { get; set; }
T-SQL
代码如下所示:

CREATE TABLE Orders
(
    Id INT IDENTITY(1,1),
    DatePlaced datetime NOT NULL,   
    CONSTRAINT PK_Order_Id PRIMARY KEY (Id)
)

CREATE TABLE OrderItems
(
    Id INT IDENTITY(1,1),
    IdOrder INT NOT NULL
        CONSTRAINT FK_OrderItems_IdOrder__Orders_Id FOREIGN KEY(IdOrder) REFERENCES Orders(Id),
    IdProduct INT NOT NULL
        CONSTRAINT FK_OrderItems_IdProduct__Products_Id FOREIGN KEY(IdProduct) REFERENCES Products(Id),
    Quantity INT NOT NULL,
    TotalPrice decimal (18,2),  
    CONSTRAINT PK_OrderItem_Id PRIMARY KEY (Id)
)

CREATE TABLE Products
(
    Id INT IDENTITY(1,1),
    Name varchar(100), 
    CONSTRAINT PK_Product_Id PRIMARY KEY (Id)
)
public partial class Order
{
    public Order()
    {
        OrderItems = new HashSet<OrderItem>();
    }

    public int Id { get; set; }

    public DateTime DatePlaced { get; set; }

    public virtual ICollection<OrderItem> OrderItems { get; set; }
}

public partial class OrderItem
{
    public int Id { get; set; }

    public int Quantity { get; set; }

    [Column(TypeName = "decimal(18,2)")]
    public decimal? TotalPrice { get; set; }

    public virtual Order Order { get; set; }
    public virtual Product Product { get; set; }
}

public partial class Product
{
    public Product() { }

    [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
    public int Id { get; set; }       

    public string Name { get; set; }
}
public async Task Add(Order order)
{
    order.Customer = _context.Customers.Find(order.Customer.Id);    
    await _context.AddAsync(order);
    await _context.SaveChangesAsync();
}
public async Task Add(Order order)
{            
    _context.Attach(order.Customer);
    foreach (var orderItem in order.OrderItems)
    {
        _context.Attach(orderItem.Product);
    }            
    await _context.Orders.AddAsync(order);
}
模型类如下所示:

CREATE TABLE Orders
(
    Id INT IDENTITY(1,1),
    DatePlaced datetime NOT NULL,   
    CONSTRAINT PK_Order_Id PRIMARY KEY (Id)
)

CREATE TABLE OrderItems
(
    Id INT IDENTITY(1,1),
    IdOrder INT NOT NULL
        CONSTRAINT FK_OrderItems_IdOrder__Orders_Id FOREIGN KEY(IdOrder) REFERENCES Orders(Id),
    IdProduct INT NOT NULL
        CONSTRAINT FK_OrderItems_IdProduct__Products_Id FOREIGN KEY(IdProduct) REFERENCES Products(Id),
    Quantity INT NOT NULL,
    TotalPrice decimal (18,2),  
    CONSTRAINT PK_OrderItem_Id PRIMARY KEY (Id)
)

CREATE TABLE Products
(
    Id INT IDENTITY(1,1),
    Name varchar(100), 
    CONSTRAINT PK_Product_Id PRIMARY KEY (Id)
)
public partial class Order
{
    public Order()
    {
        OrderItems = new HashSet<OrderItem>();
    }

    public int Id { get; set; }

    public DateTime DatePlaced { get; set; }

    public virtual ICollection<OrderItem> OrderItems { get; set; }
}

public partial class OrderItem
{
    public int Id { get; set; }

    public int Quantity { get; set; }

    [Column(TypeName = "decimal(18,2)")]
    public decimal? TotalPrice { get; set; }

    public virtual Order Order { get; set; }
    public virtual Product Product { get; set; }
}

public partial class Product
{
    public Product() { }

    [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
    public int Id { get; set; }       

    public string Name { get; set; }
}
public async Task Add(Order order)
{
    order.Customer = _context.Customers.Find(order.Customer.Id);    
    await _context.AddAsync(order);
    await _context.SaveChangesAsync();
}
public async Task Add(Order order)
{            
    _context.Attach(order.Customer);
    foreach (var orderItem in order.OrderItems)
    {
        _context.Attach(orderItem.Product);
    }            
    await _context.Orders.AddAsync(order);
}
我想要的是保存
订单
订单项
。保存代码如下所示:

CREATE TABLE Orders
(
    Id INT IDENTITY(1,1),
    DatePlaced datetime NOT NULL,   
    CONSTRAINT PK_Order_Id PRIMARY KEY (Id)
)

CREATE TABLE OrderItems
(
    Id INT IDENTITY(1,1),
    IdOrder INT NOT NULL
        CONSTRAINT FK_OrderItems_IdOrder__Orders_Id FOREIGN KEY(IdOrder) REFERENCES Orders(Id),
    IdProduct INT NOT NULL
        CONSTRAINT FK_OrderItems_IdProduct__Products_Id FOREIGN KEY(IdProduct) REFERENCES Products(Id),
    Quantity INT NOT NULL,
    TotalPrice decimal (18,2),  
    CONSTRAINT PK_OrderItem_Id PRIMARY KEY (Id)
)

CREATE TABLE Products
(
    Id INT IDENTITY(1,1),
    Name varchar(100), 
    CONSTRAINT PK_Product_Id PRIMARY KEY (Id)
)
public partial class Order
{
    public Order()
    {
        OrderItems = new HashSet<OrderItem>();
    }

    public int Id { get; set; }

    public DateTime DatePlaced { get; set; }

    public virtual ICollection<OrderItem> OrderItems { get; set; }
}

public partial class OrderItem
{
    public int Id { get; set; }

    public int Quantity { get; set; }

    [Column(TypeName = "decimal(18,2)")]
    public decimal? TotalPrice { get; set; }

    public virtual Order Order { get; set; }
    public virtual Product Product { get; set; }
}

public partial class Product
{
    public Product() { }

    [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
    public int Id { get; set; }       

    public string Name { get; set; }
}
public async Task Add(Order order)
{
    order.Customer = _context.Customers.Find(order.Customer.Id);    
    await _context.AddAsync(order);
    await _context.SaveChangesAsync();
}
public async Task Add(Order order)
{            
    _context.Attach(order.Customer);
    foreach (var orderItem in order.OrderItems)
    {
        _context.Attach(orderItem.Product);
    }            
    await _context.Orders.AddAsync(order);
}
OrderService
class:

    public async Task<OrderDto> Add(OrderDto orderDto)
    {
        var order = _mapper.Map<Order>(orderDto);
        await _orderRepository.Add(order);        
        orderDto.Id = order.Id;
        return orderDto;

    }
公共异步任务添加(OrderDto到OrderDto)
{
var order=\u mapper.Map(orderDto);
wait_orderRepository.Add(订单);
orderDto.Id=order.Id;
返回订单到;
}

请告诉我我做错了什么?请不要关闭我的问题,因为它不是重复的。

这种行为的原因是
Automapper
创建了一个新实例,实体框架认为POCO都是应该插入的新实体

因此,解决方案是
将现有实体附加到`DbContext

因此,解决方案如下所示:

CREATE TABLE Orders
(
    Id INT IDENTITY(1,1),
    DatePlaced datetime NOT NULL,   
    CONSTRAINT PK_Order_Id PRIMARY KEY (Id)
)

CREATE TABLE OrderItems
(
    Id INT IDENTITY(1,1),
    IdOrder INT NOT NULL
        CONSTRAINT FK_OrderItems_IdOrder__Orders_Id FOREIGN KEY(IdOrder) REFERENCES Orders(Id),
    IdProduct INT NOT NULL
        CONSTRAINT FK_OrderItems_IdProduct__Products_Id FOREIGN KEY(IdProduct) REFERENCES Products(Id),
    Quantity INT NOT NULL,
    TotalPrice decimal (18,2),  
    CONSTRAINT PK_OrderItem_Id PRIMARY KEY (Id)
)

CREATE TABLE Products
(
    Id INT IDENTITY(1,1),
    Name varchar(100), 
    CONSTRAINT PK_Product_Id PRIMARY KEY (Id)
)
public partial class Order
{
    public Order()
    {
        OrderItems = new HashSet<OrderItem>();
    }

    public int Id { get; set; }

    public DateTime DatePlaced { get; set; }

    public virtual ICollection<OrderItem> OrderItems { get; set; }
}

public partial class OrderItem
{
    public int Id { get; set; }

    public int Quantity { get; set; }

    [Column(TypeName = "decimal(18,2)")]
    public decimal? TotalPrice { get; set; }

    public virtual Order Order { get; set; }
    public virtual Product Product { get; set; }
}

public partial class Product
{
    public Product() { }

    [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
    public int Id { get; set; }       

    public string Name { get; set; }
}
public async Task Add(Order order)
{
    order.Customer = _context.Customers.Find(order.Customer.Id);    
    await _context.AddAsync(order);
    await _context.SaveChangesAsync();
}
public async Task Add(Order order)
{            
    _context.Attach(order.Customer);
    foreach (var orderItem in order.OrderItems)
    {
        _context.Attach(orderItem.Product);
    }            
    await _context.Orders.AddAsync(order);
}
整个代码如下所示

服务层:

public async Task<OrderDto> Add(OrderDto orderDto)
{
    var order = _mapper.Map<Order>(orderDto);
    await _orderRepository.Add(order);        
    orderDto.Id = order.Id;
    return orderDto;
}

这种行为的原因是
Automapper
创建了一个新实例,实体框架认为POCO都是应该插入的新实体

因此,解决方案是
将现有实体附加到`DbContext

因此,解决方案如下所示:

CREATE TABLE Orders
(
    Id INT IDENTITY(1,1),
    DatePlaced datetime NOT NULL,   
    CONSTRAINT PK_Order_Id PRIMARY KEY (Id)
)

CREATE TABLE OrderItems
(
    Id INT IDENTITY(1,1),
    IdOrder INT NOT NULL
        CONSTRAINT FK_OrderItems_IdOrder__Orders_Id FOREIGN KEY(IdOrder) REFERENCES Orders(Id),
    IdProduct INT NOT NULL
        CONSTRAINT FK_OrderItems_IdProduct__Products_Id FOREIGN KEY(IdProduct) REFERENCES Products(Id),
    Quantity INT NOT NULL,
    TotalPrice decimal (18,2),  
    CONSTRAINT PK_OrderItem_Id PRIMARY KEY (Id)
)

CREATE TABLE Products
(
    Id INT IDENTITY(1,1),
    Name varchar(100), 
    CONSTRAINT PK_Product_Id PRIMARY KEY (Id)
)
public partial class Order
{
    public Order()
    {
        OrderItems = new HashSet<OrderItem>();
    }

    public int Id { get; set; }

    public DateTime DatePlaced { get; set; }

    public virtual ICollection<OrderItem> OrderItems { get; set; }
}

public partial class OrderItem
{
    public int Id { get; set; }

    public int Quantity { get; set; }

    [Column(TypeName = "decimal(18,2)")]
    public decimal? TotalPrice { get; set; }

    public virtual Order Order { get; set; }
    public virtual Product Product { get; set; }
}

public partial class Product
{
    public Product() { }

    [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
    public int Id { get; set; }       

    public string Name { get; set; }
}
public async Task Add(Order order)
{
    order.Customer = _context.Customers.Find(order.Customer.Id);    
    await _context.AddAsync(order);
    await _context.SaveChangesAsync();
}
public async Task Add(Order order)
{            
    _context.Attach(order.Customer);
    foreach (var orderItem in order.OrderItems)
    {
        _context.Attach(orderItem.Product);
    }            
    await _context.Orders.AddAsync(order);
}
整个代码如下所示

服务层:

public async Task<OrderDto> Add(OrderDto orderDto)
{
    var order = _mapper.Map<Order>(orderDto);
    await _orderRepository.Add(order);        
    orderDto.Id = order.Id;
    return orderDto;
}

另一个解决方案是使用
\u mapper.Map(sourceProperty,destinationProperty)。这不会更改引用。但是,在设置配置时,请确保忽略不希望映射的属性(即主键)

e、 g.在映射配置文件类的构造函数下:

CreateMap<SourceType, DestinationType>()
.ForMember(destination => destination.PK, options => options.Ignore());
CreateMap()
.ForMember(destination=>destination.PK,options=>options.Ignore());

另一种解决方案是使用
\u mapper.Map(sourceProperty,destinationProperty)。这不会更改引用。但是,在设置配置时,请确保忽略不希望映射的属性(即主键)

e、 g.在映射配置文件类的构造函数下:

CreateMap<SourceType, DestinationType>()
.ForMember(destination => destination.PK, options => options.Ignore());
CreateMap()
.ForMember(destination=>destination.PK,options=>options.Ignore());

该错误适用于
产品
表,但您显示的代码适用于
订单
订单项
表。你能展示一下
产品的代码吗?@devNull,请看我更新的问题。插入产品本身似乎是一个错误。我不是EF专家,我会评论而不是回答,但我相信
AddAsync
会将实体添加到添加状态的上下文中,因此它会尝试插入它。它已经有了一个id,因为您刚刚(大概)找到了它的
。我认为您可以删除
Add()
方法中的第二行代码。@GertArnold您的意思是再次插入产品吗?错误是针对
Products
表的,但您显示的代码是针对
Orders
OrderItems
表的。你能展示一下
产品的代码吗?@devNull,请看我更新的问题。插入产品本身似乎是一个错误。我不是EF专家,我会评论而不是回答,但我相信
AddAsync
会将实体添加到添加状态的上下文中,因此它会尝试插入它。它已经有了一个id,因为您刚刚(大概)找到了它的
。我想您可以删除
Add()
方法中的第二行代码。@GertArnold您是说产品会再次插入吗?