ASP.NET MVC 中一对多关系 ViewModel 的 CRUD 操作

问题描述 投票:0回答:2

这几天我一直在网上寻找,但仍然没有得到我想要的东西。也许是我的研究方式是错误的。但这是问题所在 我有一个订单模型

public class Order
    {
        [Key]
        public int Id { get; set; }

        public int TotalItems { get; set; }

        public DateTime DeliveryDate { get; set; }

        public string OrderNumber { get; set; }
        public string DeliveryAddress { get; set; }

        [ForeignKey("ClientId")]
        public int ClientId { get; set; }
        

        public int OrderItemId { get; set; }
        [ForeignKey("OrderItemId")]

        public List<OrderItem> OrderItems { get; set; }
        public Client Client { get; set; }
    }

还有 OrderItem 模型

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

        [ForeignKey("OrderId")]
        public int OrderId{ get; set; }

        public int InventoryInfoId { get; set; }
        [ForeignKey("InventoryInfoId")]

        [Required]
        public string ItemCode { get; set; }

        public int Quantity { get; set; }
        public virtual InventoryInfo InventoryInfo { get; set; }
        public Order Order { get; set; }
    }

根据用户输入,一个订单可以有多个订单项。 这是我的 OrderViewModel

public class OrderViewModel
    {
        //public int OrderId { get; set; }
        //public string OrderNumber { get; set; }
        //public string DeliveryAddress { get; set; }
        //public int ClientId { get; set; }
        //public DateTime Deliverydate { get; set; }
        public Order Order { get; set; }
        public IList<OrderItem> OrderItems { get; set; }
        public int ItemCode { get; set; }
        public int Quantity { get; set; }
    }

这是我的Create.cshtml

<div class="row">
    <div class="col-md-4">
        <form asp-action="Create">
            <div asp-validation-summary="All" class="text-danger"></div>
            <div class="form-group">
                <label asp-for="Order.ClientId" class="control-label"></label>
                <select asp-for="Order.ClientId" class="form-control" asp-items="ViewBag.ClientId">
                    <option>-- Select Client --</option>
                </select>
                <span asp-validation-for="Order.ClientId" class="text-danger"></span>

            </div>
            <div class="form-group">
                <label asp-for="Order.OrderNumber" class="control-label"></label>
                <input asp-for="Order.OrderNumber" class="form-control" />
                <span asp-validation-for="Order.OrderNumber" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="Order.DeliveryDate" class="control-label"></label>
                <input type="date" data-val="true" asp-for="Order.DeliveryDate" class="form-control" />
                <span asp-validation-for="Order.DeliveryDate" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="Order.DeliveryAddress" class="control-label"></label>
                <input asp-for="Order.DeliveryAddress" class="form-control" />
                <span asp-validation-for="Order.DeliveryAddress" class="text-danger"></span>
            </div>

            <table id="tblCustomers" class="table" cellpadding="0" cellspacing="0">
                <thead>
                    <tr>
                        <th style="width:150px">Item Code</th>
                        <th style="width:150px">Quantity</th>
                        <th></th>
                    </tr>
                </thead>
                <tbody></tbody>
                <tfoot id="item-list">
                    <tr>
                        <td>
                            <select asp-for="OrderItems[0].ItemCode" class="items" asp-items="@ViewBag.Item"></select>
                        </td>
                        <td><input type="text" asp-for="OrderItems[0].Quantity" class="items" /></td>
                        @*<td><input type="button" id="btnAdd" value="Add" /></td>*@
                    </tr>
                </tfoot>
            </table>
            <button id="add">Add another item</button>

            <div class="form-group">
                <input type="submit" value="Create" class="btn btn-default" />
            </div>

        </form>
    </div>

</div>



@section Scripts {
    @{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
    <script>
        $("#add").click(function (e) {
           e.preventDefault();
           var i = ($(".items").length) / 2;
           var model = @Html.Raw(@ViewBag.Items);
            var n = '<tr><td><select id="OrderItems_' + 1 + '_ItemCode" name="OrderItems[' + 1 + '].ItemCode" class="items" /></td>' +
            '<td><input type="text" class="items" name="OrderItems[' + 1 + '].Quantity" /></td></tr>'

           $("#item-list").append(n);

           var Items = "";
           $(model).each(function (e) {
               Items = Items + '<option value="' + this.Value + '">' + this.Text + '</option>'
           });

           var subItemList = $("#OrderItems" + 1 + "_ItemCode");
            subItemList.empty();
            subItemList.append(Items);
    });
    </script>

}

用户有两部分,订单详情和订单项目 这是我的 OrdersController Create

[HttpPost]
        [ValidateAntiForgeryToken]
        public async Task<IActionResult> Create([Bind("ClientId", "OrderNumber", "DeliveryDate", "DeliveryAddress")]OrderViewModel OrderVM)
        {

            try
            {
                if (ModelState.IsValid)
                {
                    var order = new Order()
                    {
                        Id = OrderVM.OrderId,
                        DeliveryAddress = OrderVM.DeliveryAddress,
                        DeliveryDate = OrderVM.Deliverydate,
                        OrderNumber = OrderVM.OrderNumber
                    };
                    _context.Add(order);
                    await _context.SaveChangesAsync();
                    return RedirectToAction(nameof(Index));
                }
            }
            catch (DbUpdateException ex)
            {
                //Log the error(uncomment ex variable name and write a log.
                ModelState.AddModelError("", "Unable to save changes. " +
                    "Try again, and if the problem persists " +
                    "see your system administrator.");
            }
            PopulateClientDropDownList(OrderVM.ClientId);
            CreateMultipleOrderItem();
            return View(OrderVM);
        }

我现在实际上很迷茫,因为我已经尝试了几个教程并查看了示例,但似乎没有什么可以帮助我解决这个问题。也许我无法理解他们。请大家帮帮我!

在杰弗里的帮助下。

[HttpPost]
        [ValidateAntiForgeryToken]
        public async Task<IActionResult> Create(OrderViewModel OrderVM)
        {

            try
            {
                if (ModelState.IsValid)
                {
                    //var order = new Order()
                    //{
                    //    Id = OrderVM.OrderId,
                    //    DeliveryAddress = OrderVM.DeliveryAddress,
                    //    DeliveryDate = OrderVM.Deliverydate,
                    //    OrderNumber = OrderVM.OrderNumber
                    //};
                    _context.AddRange(OrderVM);
                    
                    //_context.AddRange(OrderVM.OrderItems);
                    await _context.SaveChangesAsync();
                    return RedirectToAction(nameof(Index));
                }
            }
            catch (DbUpdateException ex)
            {
                //Log the error(uncomment ex variable name and write a log.
                ModelState.AddModelError("", "Unable to save changes. " +
                    "Try again, and if the problem persists " +
                    "see your system administrator.");
            }
            PopulateClientDropDownList(OrderVM.Order.ClientId);
            CreateMultipleOrderItem();
            return View(OrderVM);
        }

控制器的编辑版本允许数据从我的视图页面传递到控制器。但是出现错误。InvalidOperationException:未找到实体类型“OrderViewModel”。确保实体类型已添加到模型中。 Microsoft.EntityFrameworkCore.ChangeTracking.Internal.StateManager.GetOrCreateEntry(对象实体)

c# jquery asp.net-mvc asp.net-core model-view-controller
2个回答
2
投票

尝试这样的事情

    [HttpPost]
    [ValidateAntiForgeryToken]
    public async Task<IActionResult> Create(OrderViewModel OrderVM)
    {

        try
        {
            if (ModelState.IsValid)
            {
                var order = new Order()
                {
                    // Id = OrderVM.OrderId,- Primary keys will be auto generated
                    DeliveryAddress = OrderVM.DeliveryAddress,
                    DeliveryDate = OrderVM.Deliverydate,
                    OrderNumber = OrderVM.OrderNumber,
                    ClientId = OrderVM.ClientId,
                    TotalItems = OrderVM.TotalItems,
                    OrderItems = OrderVM.Select(item => new OrderItem()
                    {
                     ItemCode = item.ItemCode,
                     Quantity = item.Quantity,
                     InventoryInfoId = item.InventoryInfoId
      
                    }).ToList()
                };
                await _context.Orders.AddAsync(order);
                
                //_context.AddRange(OrderVM.OrderItems);
                await _context.SaveChangesAsync();

                return RedirectToAction(nameof(Index));
            }
        }
        catch (DbUpdateException ex)
        {
            //Log the error(uncomment ex variable name and write a log.
            ModelState.AddModelError("", "Unable to save changes. " +
                "Try again, and if the problem persists " +
                "see your system administrator.");
        }
        PopulateClientDropDownList(OrderVM.Order.ClientId);
        CreateMultipleOrderItem();
        return View(OrderVM);
    }

0
投票
public class ServiceController : Controller
{
    private readonly AppDbContext _context;

    private readonly IWebHostEnvironment _env;

    public ServiceController(AppDbContext context, IWebHostEnvironment env)
    {
        _context = context;
        _env = env;
    }
    public async Task<IActionResult> Index()
    {
        List<Service> services = await _context.Services.ToListAsync();
        return View(services);
    }
    public IActionResult Create()
    {
        return View();
    }
    [HttpPost]
    public async Task<IActionResult> Create(CreateServiceVM create)
    {
        if (!ModelState.IsValid) return BadRequest();
        bool result = await _context.Services.AnyAsync(n => n.Title.Trim().ToLower() == create.Title.Trim().ToLower());
        if (result)
        {
            ModelState.AddModelError("Title", "Does Exist");
            return View(create);
        }
        if (!create.Photo.ValidateType())
        {
            ModelState.AddModelError("Photo", "type not valid");
            return View(create);
        }
        if (!create.Photo.ValidateSize(10))
        {
            ModelState.AddModelError("Photo", "max 10mb");
            return View(create);
        }
        Service model = new Service()
        {
            Title = create.Title,
            Description = create.Description,
            Image = await create.Photo.CreateAsync(_env.WebRootPath, "assets", "img", "services")
        };
        await _context.Services.AddAsync(model);
        await _context.SaveChangesAsync();
        return RedirectToAction(nameof(Index));
    }
    public async Task<IActionResult> Update(int id)
    {
        if (id <= 0) return BadRequest();
        Service service = await _context.Services.FirstOrDefaultAsync(s => s.Id == id);
        if (service == null) return NotFound();
        UpdateServiceVM update = new()
        {
            Title = service.Title,
            Description = service.Description
        };
        return View(update);
    }
    public async Task<IActionResult> Update(int id, UpdateServiceVM update)
    {
        if (!ModelState.IsValid) return BadRequest();
        Service service = _context.Services.FirstOrDefault(s => s.Id == id);
        if (service is null)
        {
            return NotFound();
        }
        bool result = await _context.Services.AnyAsync(n => n.Title.Trim().ToLower() == update.Title.Trim().ToLower());
        if (result)
        {
            ModelState.AddModelError("Title", "Does Exist");
            return View(update);
        }
        if (update.Photo is not null)
        {
            if (!update.Photo.ValidateType())
            {
                ModelState.AddModelError("Photo", "Type not valid");
                return View(update);
            }
            if (!update.Photo.ValidateSize(10))
            {
                ModelState.AddModelError("Photo", "max 10mb");
                return View(update);
            }
            service.Image.Delete(_env.WebRootPath, "assets", "img", "service");
            service.Image = await update.Photo.CreateAsync(_env.WebRootPath, "assets", "img", "service");

        }
        service.Title = update.Title;
        service.Description = update.Description;

        await _context.SaveChangesAsync();

        return RedirectToAction(nameof(Index));
    }
    public async Task<IActionResult> Delete(int id)
    {
        if (id <= 0) return BadRequest();
        Service service = _context.Services.FirstOrDefault(s => s.Id == id);
        if (service is null) return NotFound();
      
        _context.Remove(service);
        await _context.SaveChangesAsync();
        return RedirectToAction(nameof(Index));
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.