SqlException: невозможно вставить значение NULL в столбец «CarId», таблица «AutoServiceDb.dbo.ServiceOrders»; столбец не допускает пустых значений. ВСТАВИТЬ не удается

Когда я хочу добавить новую запись, выдает ошибку

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 AddNewOrder

@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">&#10004;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">&#10002;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);



    }

}

введите здесь описание изображения

Модель автомобиля

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; }



    }
}

person Ярослав Деренівський    schedule 24.02.2020    source источник
comment
Ошибка говорит вам о проблеме. Как насчет этого вы не понимаете?   -  person Larnu    schedule 24.02.2020
comment
Он ясно говорит, что CardId не может быть пустым.   -  person Hamed Moghadasi    schedule 24.02.2020
comment
Вы можете добавить Car модель к вопросу!   -  person Hamed Moghadasi    schedule 24.02.2020
comment
Если ваш CarId должен быть столбцом идентификации, проверьте этот ответ - stackoverflow.com/questions/10013313/   -  person SᴇM    schedule 24.02.2020
comment
Свойство навигации ServiceOrder.Car помечено как виртуальное?   -  person Claudio Valerio    schedule 24.02.2020


Ответы (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 имеет значение null, когда вы пытаетесь вставить его в SQL, база данных пытается вставить NULL в CarId.

person Kyle B    schedule 24.02.2020