SqlException:无法将值 NULL 插入列“CarId”、表“AutoServiceDb.dbo.ServiceOrders”;列不允许空值。插入失败
Posted
技术标签:
【中文标题】SqlException:无法将值 NULL 插入列“CarId”、表“AutoServiceDb.dbo.ServiceOrders”;列不允许空值。插入失败【英文标题】:SqlException: Cannot insert the value NULL into column 'CarId', table 'AutoServiceDb.dbo.ServiceOrders'; column does not allow nulls. INSERT fails 【发布时间】:2020-02-24 11:02:02 【问题描述】:当我想添加一个新条目时,它会抛出一个错误
SqlException:无法将值 NULL 插入到列“CarId”、表“AutoServiceDb.dbo.ServiceOrders”中;列不允许空值。插入失败。声明已终止。
以下是控制器代码、DTO、服务和 Blazor 控制器
using System;
using Microsoft.AspNetCore.Mvc;
using AutoService.Domain.Entities;
using AutoService.Application.Interfaces;
using System.Threading.Tasks;
using AutoService.API.Models;
using AutoMapper;
using AutoService.Application.DTOs;
namespace AutoService.API.Controllers
[ApiController]
[Route("[controller]")]
public class ServiceOrderController : ControllerBase
private readonly IServiceOrderService _serviceOrder;
private readonly IMapper _mapper;
public ServiceOrderController(IServiceOrderService serviceOrder , IMapper mapper)
_serviceOrder = serviceOrder;
_mapper = mapper;
[HttpPost("scheduleservice")]
public IActionResult ScheduleService([FromBody] ScheaduleViewModel model)
var order = _mapper.Map<ScheaduleViewModel, OrderDTO>(model);
var result = _serviceOrder.ScheduleService(order);
if (result == null) return BadRequest();
return Ok(result);
[HttpGet]
public async Task<IActionResult> GetService()
var result = await _serviceOrder.GetServicesAsync();
return Ok(result);
订购DTO
using System;
using System.Collections.Generic;
using System.Text;
namespace AutoService.Application.DTOs
public class OrderDTO
//create
public string ClientName get; set;
public string ClientPhone get; set;
public string CarMake get; set;
public string CarModel get; set;
public string CarPlate get; set;
public string CarColor get; set;
public DateTime ScheduledDate get; set;
服务
using AutoService.Application.DTOs;
using AutoService.Application.Interfaces;
using AutoService.Domain.Entities;
using AutoService.Infrastructure.Context;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace AutoService.Application.Services
public class ServiceOrderService : IServiceOrderService
private readonly ServicingContext _context;
public ServiceOrderService(ServicingContext context)
_context = context;
public async Task CreateService(ServiceOrder serviceOrder)
_context.ServiceOrders.Add(serviceOrder);
await _context.SaveChangesAsync();
public async Task<List<ServiceOrder>> GetServicesAsync()
var result = await _context.ServiceOrders
.Include(c => c.Client)
.Include(k => k.Car)
.ToListAsync();
return result;
public ServiceOrder ScheduleService(OrderDTO orderDTO)
var client = _context.Clients.FirstOrDefault(c => c.FirstName == orderDTO.ClientName);
if (client == null)
_context.Clients.Add(new Client
FirstName = orderDTO.ClientName,
PhoneNumber = orderDTO.ClientPhone
);
var car = _context.Cars.Where((c => c.Makes == orderDTO.CarMake && c.Model == orderDTO.CarModel && c.Color == orderDTO.CarColor && c.LicensePlate == orderDTO.CarPlate)).FirstOrDefault();
if (car == null)
var entity = _context.Cars.Add(new Car
Makes = orderDTO.CarMake,
Model = orderDTO.CarModel,
Color = orderDTO.CarColor,
LicensePlate = orderDTO.CarPlate
);
var serviceOrder = _context.Add(new ServiceOrder
Client = client,
Car = car,
ScheduledTime = orderDTO.ScheduledDate,
CreationDate = DateTime.UtcNow
);
_context.SaveChanges();
return serviceOrder.Entity;
Blazor 页面添加新订单
@page "/addServiceOrder"
@using System.Text.Json
@using System.Text
@using AutoService.API.Models
<link rel="stylesheet" href="css/bootstrap/bootstrap.min.css" />
<link href="css/site.css" rel="stylesheet" />
<form method="post">
<table>
<label ></label>
<tr>
<td>Client name:</td>
<td><input @bind="ClientName" /></td>
</tr>
<tr>
<td>Client phone</td>
<td><input @bind="ClientPhone" /></td>
</tr>
<tr>
<td>Car model</td>
<td><input @bind="CarModel" /></td>
</tr>
<tr>
<td>Car make</td>
<td><input @bind="CarMake" /></td>
</tr>
<tr>
<td>Car plate</td>
<td><input @bind="CarPlate" /></td>
</tr>
<tr>
<td>Car color</td>
<td><input @bind="CarColor" /></td>
</tr>
<tr>
<td>Scheduled date</td>
<td><input @bind="ScheduledDate" /></td>
</tr>
</table>
<a class="btn btn-secondary" href="serviceOrder">Back</a>
<button type="button" class="btn btn-primary" @onclick="AddNewOrder">✔Add</button> @Alert
<p />
</form>
<h1>Add service order</h1>
<p />
@code
@inject IHttpClientFactory clientFactory;
protected string ClientName get; set;
protected string ClientPhone get; set;
protected string CarMake get; set;
protected string CarModel get; set;
protected string CarPlate get; set;
protected string CarColor get; set;
protected DateTime ScheduledDate get; set;
protected string Alert get; set;
protected async Task AddNewOrder()
Alert = " ";
if (ClientName == string.Empty || ClientPhone == string.Empty || CarMake == string.Empty || CarModel == string.Empty || CarPlate == string.Empty || CarColor == string.Empty || ScheduledDate == DateTime.Now)
Alert = "Fill all fields!";
return;
Alert = "Added new order";
var _client = clientFactory.CreateClient();
ScheaduleViewModel _newOrder = new ScheaduleViewModel ClientName = ClientName, ClientPhone = ClientPhone, CarMake = CarMake, CarModel = CarModel, CarPlate = CarPlate, CarColor = CarColor, ScheduledDate = ScheduledDate, ;
var _content = new StringContent(JsonSerializer.Serialize(_newOrder), Encoding.UTF8, "application/json");
await _client.PostAsync("https://localhost:5001/ServiceOrder/scheduleservice", _content);
Blazor 页面“ServiceOrder”
@page "/serviceOrder"
@using AutoService.Domain.Entities
@using System.Text.Json
<h1>Service order</h1>
<p />
<a class="btn btn-primary" href="addServiceOrder">✒Add order</a>
<p />
@if (ServiceOrdersList == null)
<div>Loading...</div>
else
<table class="table">
<thead>
<tr>
<td>Id</td>
<td>Firs name owner</td>
<td>Car model</td>
<td>Creation </td>
<td>Scheduled time</td>
</tr>
</thead>
<tbody>
@foreach (var serviceOrder in ServiceOrdersList)
<tr>
<td>@serviceOrder.Id</td>
<td>@serviceOrder.Client.FirstName</td>
<td>@serviceOrder.Car.Model</td>
<td>@serviceOrder.CreationDate</td>
<td>@serviceOrder.ScheduledTime</td>
</tr>
</tbody>
</table>
@code
public List<ServiceOrder> ServiceOrdersList get; set;
@inject IHttpClientFactory _clientFactory;
protected string info;
protected override async Task OnInitializedAsync()
var client = _clientFactory.CreateClient();
var result = await client.GetAsync("https://localhost:5001/serviceOrder");
info = await result.Content.ReadAsStringAsync();
var options = new JsonSerializerOptions
IgnoreNullValues = true,
PropertyNameCaseInsensitive = true
;
ServiceOrdersList = JsonSerializer.Deserialize<List<ServiceOrder>>(info, options);
enter image description here
车型
using System;
using System.Collections.Generic;
using System.Text;
namespace AutoService.Domain.Entities
public class Car
public int Id get; set;
public string Makes get; set;
public string Model get; set;
public string Color get; set;
public string LicensePlate get; set;
【问题讨论】:
错误告诉你问题所在。不明白怎么办? 上面明确写着CardId
不能为空。
你能把Car
模型添加到问题中吗!
如果您的 CarId
应该是身份列,请检查此答案 - ***.com/questions/10013313/…
ServiceOrder.Car 导航属性是否标记为虚拟?
【参考方案1】:
您似乎没有将新的“实体”分配给您尝试创建的“汽车”对象...
var car = _context.Cars.Where(...).FirstOrDefault();
if (car == null)
var entity = _context.Cars.Add(new Car
...
);
var serviceOrder = _context.Add(new ServiceOrder
Client = client,
Car = car, // <-- 'car' is still null when you assign it's value to the service order
...
尝试添加如下内容:
var car = _context.Cars.Where(...).FirstOrDefault();
if (car == null)
car = new Car // Assign the new car to the null car variable.
...
;
_context.Cars.Add(car); // Then add it to the context.
由于“ServiceOrder.Car”属性在尝试将其插入 SQL 时为空,因此数据库会尝试将 NULL 插入 CarId。
【讨论】:
以上是关于SqlException:无法将值 NULL 插入列“CarId”、表“AutoServiceDb.dbo.ServiceOrders”;列不允许空值。插入失败的主要内容,如果未能解决你的问题,请参考以下文章
无法将值 NULL 插入列 - 如何强制标识增加? [关闭]