【问题标题】:SaveChanges() duplicates records. one null record and the other one is fineSaveChanges() 复制记录。一个空记录,另一个很好
【发布时间】:2019-05-06 04:14:05
【问题描述】:

我正在使用 ASP.NET MVC 5 和实体框架。

我有这三个模型类:

public class SubCat
{
        public int Id { get; set; }
        public string Description { get; set; }

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

public class Item
{
        public Item()
        {
            Images = new HashSet<Image>();
        }

        public int Id { get; set; }
        public string Description { get; set; }

        [ForeignKey("SubCat")]
        public int? SubCatId { get; set; }
        public SubCat SubCat { get; set; }

        //public byte? Image { get; set; }

        [ForeignKey("Images")]
        public int? ImageId { get; set; }
        public ICollection<Image> Images { get; set; }

        public int ItemPoints { get; set; }
        public int? PointsValue { get; set; }

        public string Status { get; set; }

        [Display(Name = "Delivery")]
        public string DeliveryChoice { get; set; }

        public bool? Approved { get; set; }

        public bool? Bartered { get; set; }
}

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

        [DisplayName("Upload File")]
        public string Picture { get; set; }

        [NotMapped]
        public HttpPostedFileBase ImageFile { get; set; }

        [ForeignKey("Item")]
        public int? ItemId { get; set; }
        public Item Item { get; set; }
}

当我添加一个新项目时,我需要给它一个子类别 ID 以便在视图中显示它,这是我添加新项目的方法:

形式:

@using (Html.BeginForm("ItemSubmit", "Orders", FormMethod.Post, new { enctype = "multipart/form-data" }))
                            {
                                <div class="form-group">
                                    @Html.LabelFor(m => m.Item.Description, new { @class = "col-md-2 control-label" })
                                    @Html.TextBoxFor(m => m.Item.Description, new { @class = "form-control" })
                                </div>
                                <br />
                                <div class="form-group">
                                    <div class="col-md-6">
                                        @Html.DropDownListFor(m => m.Category.Id, new SelectList(Model.Categories, "Id", "Description"), "Select Category", new { @class = "form-control", @id = "cats" })
                                    </div>
                                    <div class="col-md-6">
                                        <select id="subs" disabled class="dropdown form-control" name="subCategory">
                                            <option>Select Category First</option>
                                        </select>

                                    </div>
                                    <br />
                                    <br />
                                    <br />
                                    <div class="form-group">
                                        @Html.LabelFor(m => m.Item.Status, new { @class = "col-md-2 control-label" })
                                        @Html.DropDownListFor(m => m.Item.Status, new SelectList(Model.Items, "Status", "Status"), "", new { @class = "form-control" })
                                    </div>
                                    <br />
                                    <div class="form-group">
                                        @Html.LabelFor(m => m.Item.DeliveryChoice, new { @class = "col-md-2 control-label" })
                                        @Html.DropDownListFor(m => m.Item.DeliveryChoice, new SelectList(Model.Items, "DeliveryChoice", "DeliveryChoice"), "", new { @class = "form-control" })
                                    </div>
                                    <div class="form-group">
                                        <div class="col-md-1"></div>
                                        <h3><span class="label label-primary">How many points would you suggest for your Item?</span></h3>
                                        <div class="col-md-3"></div>
                                        @Html.TextBoxFor(m => m.Item.ItemPoints, new { @class = "form-control" })
                                    </div>
                                    <div class="form-group">
                                        @Html.LabelFor(m => m.Image.Picture, htmlAttributes: new { @class = "control-label col-md-2" })

                                        <input type="file" name="ImageFile" required>

                                    </div>
                                    <br />
                                    <br />


                                    <div class="row">
                                        <button type="submit" class="btn btn-success">Submit</button>
                                    </div>
                                </div>
                            }

和控制器:

[HttpPost]
        public ActionResult ItemSubmit(Item item, int subCategory, Image imageModel, Order order, ApplicationUser user)
        {
            if (ModelState.IsValid)
            {
                    var sub = _context.SubCats.SingleOrDefault(m => m.Id == subCategory);

                    //Item
                    item.SubCatId = sub.Id;

                    //Image
                    string fileName = Path.GetFileNameWithoutExtension(imageModel.ImageFile.FileName);
                    string extension = Path.GetExtension(imageModel.ImageFile.FileName);
                    fileName = fileName + DateTime.Now.ToString("yymmssfff") + extension;
                    imageModel.Picture = "~/Image/" + fileName;
                    fileName = Path.Combine(Server.MapPath("~/Image/"), fileName);
                    imageModel.ImageFile.SaveAs(fileName);



                    //Order
                    order.OrderDate = DateTime.Now;
                    order.TransactionType = "Item Submit";
                    order.UserId = User.Identity.GetUserId();
                    order.Approved = false;
                    order.ItemId = item.Id;


                    _context.Items.Add(item);
                    _context.Images.Add(imageModel);
                    _context.Orders.Add(order);
                    _context.SaveChanges();


            }


            return RedirectToAction("Index","Home");
        }

但是当 _context.SaveChanges() 被调用时,ef 倾向于保存项目的两个副本!一个有subcatid,一个没有subcatid,有趣的是图像采用了没有subcatid的项目的itemid,所以当我尝试通过图像在视图上显示项目时它不会显示,因为显示的项目必须与选择的子猫有关。

这是我在视图中使用的 jquery:

$(document).ready(function () {
            $(".mybtn").on('click', function () {
                var id = $(this).attr('data-id');
                $("#images").html('');
                $.get("/Items/GetSubById", { ID: id }, function (data) {
                    $("#sub-categories-btns").html(``);
                    for (var i = 0; i < data.length; i++) {
                        $("#sub-categories-btns").append(`
                        <button id="button" type="button" data-id="`+ data[i].Id + `" class="btn btn-success my-subcategory-btn">
                            `+ data[i].Description +`
                        </button>
                    `);
                    }
                });
            });

            $("#sub-categories-btns").delegate(".my-subcategory-btn", 'click', function () {
                var subId = $(this).attr('data-id');
                $("#images").html('');
                $.get("/Items/GetImgaesBySubCategoryId", { ID: subId }, function (data) {
                    for (var i = 0; i < data.length; i++) {
                        $("#images").append(`
                            <div class="form-group col-md-4">
                                <button data-id="`+ data[i].ItemId +`" name="item" class="ItemInfo img-btn"><img src="`+ data[i].Picture +`" width="200" height="200" /></button>
                            </div>
                        `);
                    }
                });
            });

            $("#images").delegate('.img-btn', 'click', function () {
                var imgId = $(this).attr('data-id');
                window.location.href = "/Items/Buy?item=" + imgId;
            });

        });

这是我发送到视图的 json:

public JsonResult GetSubById(int? ID)
        {
            return Json(_context.SubCats.Where(p => p.CategoryId == ID), JsonRequestBehavior.AllowGet);
        }
        public JsonResult GetImgaesBySubCategoryId(int? ID)
        {
            var data = _context.Images.Where(m => m.Item.SubCatId == ID).ToList();
            data.ForEach(img => img.Picture = img.Picture.Replace("~", ""));
            return Json(data, JsonRequestBehavior.AllowGet);
        }

如何阻止它重复??

【问题讨论】:

  • 您能说明调用ItemSubmit 的方法如何获取这些参数并传递给它吗?
  • 刚才在控制器上面做了
  • _context.SaveChanges() 被调用,ef 倾向于保存项目的两个副本 方法ItemSubmit 是否调用了两次?您可以调试您的应用程序并在该方法上放置一个断点,以查看它是否被调用了两次。

标签: c# asp.net-mvc entity-framework asp.net-mvc-5


【解决方案1】:

其实我早就找到了解决方案,但我忘了在这里发帖!

我不知道如何解释它,但是在创建图像时,它用一个新项目填充了项目导航属性,该项目的信息与表单发送的项目相同! 所以我只是在ItemSubmit Controller中上传图片代码之前添加了这两行

imageModel.Item = null;
imageModel.ItemId = item.Id;

我在从视图模型发送的模型中也有问题,所以我评论了 if(ModelState.IsValid)

希望这对其他人有所帮助

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-15
    • 1970-01-01
    • 2017-03-24
    • 1970-01-01
    相关资源
    最近更新 更多