C# 编辑方法不使用外键

C# 编辑方法不使用外键,c#,asp.net-mvc,asp.net-mvc-5,C#,Asp.net Mvc,Asp.net Mvc 5,我的事件模型的编辑方法遇到了一个问题,我注意到我所做的更改没有保存到数据库中,即使它似乎在代码中工作(我已经用断点进行了修改,所有行都在执行),我有一种感觉,外键可能导致了一些问题,但我不确定 这是我正在使用的模型: public class Event { //ID [Key] [DatabaseGenerated(DatabaseGeneratedOption.Identity)] public int EventID { get; set; } /

我的事件模型的编辑方法遇到了一个问题,我注意到我所做的更改没有保存到数据库中,即使它似乎在代码中工作(我已经用断点进行了修改,所有行都在执行),我有一种感觉,外键可能导致了一些问题,但我不确定

这是我正在使用的模型:

public class Event
{
    //ID
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int EventID { get; set; }

    //User ID Foregin Key
    public string OwnerID { get; set; }

    //Foreign Key for Club
    public int VenueID { get; set; }
    [ForeignKey("VenueID")]
    public virtual Venue Venue { get; set; }

    //Title
    [Required(ErrorMessage = "You must enter a title")]
    [DataType(DataType.Text)]
    [Display(Name = "Title")]
    public string EventTitle { get; set; }

    //Date
    [Required(ErrorMessage = "You must enter a date")]
    [DataType(DataType.Date)]
    [DisplayFormat(DataFormatString = "{0:dd/MM/yyyy}", ApplyFormatInEditMode = true)]
    [Display(Name = "Date")]
    public DateTime EventDate { get; set; }

    //Time
    [Required(ErrorMessage = "You must enter a start time")]
    [DataType(DataType.Time)]
    [DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:HH:mm}")]
    [Display(Name = "Time")]
    public DateTime EventTime { get; set; }

    //Description
    [Required(ErrorMessage = "Give your event a brief description")]
    [DataType(DataType.MultilineText)]
    [Display(Name = "Details")]
    public string EventDescription { get; set; }

    //Event Category
    [Required(ErrorMessage = "You must select a category from the list")]
    [Display(Name = "Category")]
    public Category EventCategory { get; set; }

    //Youtube Link     
    [Display(Name = "YouTube")]
    public string EventYouTube { get; set; }

    //SoundCloud Link
    [Display(Name = "SoundCloud")]
    public string EventSoundCloud { get; set; }

    //Facebook Link
    [Display(Name = "Facebook")]
    public string EventFacebook { get; set; }

    //Twitter Link
    [Display(Name = "Twitter")]
    public string EventTwitter { get; set; }

    //Instagram Link
    [Display(Name = "Instagram")]
    public string EventInstagram { get; set; }

    //Official Website Link
    [Display(Name = "Website")]
    [DataType(DataType.Url, ErrorMessage = "This is not a valid Url")]
    public string EventWebsite { get; set; }

    //Ticket Price
    [Display(Name = "Ticket Price")]
    public double? EventTicketPrice { get; set; }

    //Ticket Shop Link/ Location
    [Display(Name = "Ticket Vendor")]
    public string EventTicketStore { get; set; }

    //Image File 
    public virtual ICollection<File> Files { get; set; }
}

public class File
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int FileId { get; set; }

    [StringLength(255)]
    public string FileName { get; set; }

    [StringLength(100)]
    public string ContentType { get; set; }

    public byte[] Content { get; set; }

    public FileType FileType { get; set; }

    public int EventID { get; set; }

    public virtual Event Event { get; set; }
}

public class Venue
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int VenueID { get; set; }

    //Id for the owner of this venue
    public string OwnerId { get; set; }

    //List of events for this venue
    public List<Event> VenueEvents { get; set; }

    //Name
    [Required(ErrorMessage = "You must enter a name")]
    [DataType(DataType.Text)]
    [Display(Name = "Name")]
    public string VenueName { get; set; }

    //Type
    [DataType(DataType.Text)]
    [Display(Name = "Type")]
    public VenueType VenueType { get; set; }

    //Town
    [Required(ErrorMessage = "You must select a town from the list provided")]
    [Display(Name = "Town")]
    public Town VenueTown { get; set; }

    //Address
    [Required(ErrorMessage = "You must enter a street")]
    [DataType(DataType.Text)]
    [Display(Name = "Street")]
    public string VenueAddress { get; set; }

    //Description
    [Required(ErrorMessage = "Give your venue a brief description")]
    [DataType(DataType.MultilineText)]
    [Display(Name = "Details")]
    public string VenueDescription { get; set; }

    //Contact Email
    [Display(Name = "Email")]
    [DataType(DataType.EmailAddress, ErrorMessage = "This is not a valid email address")]
    public string VenueEmail { get; set; }

    //Contact Number
    [Display(Name = "Telephone")]
    [DataType(DataType.PhoneNumber, ErrorMessage = "This is not a valid phone number")]
    public string VenuePhoneNumber { get; set; }

    //Image File 
    public virtual ICollection<VenueFile> VenueFiles { get; set; }
}
这正确地反映了我在“编辑”视图中所做的更改,但这些更改在我的数据库中似乎没有更改

我还注意到,在完成此方法之后,它总是在转到details方法之前跳转到dispose方法
db.Entry(@event.State=EntryState.Modified

然后保存更改

您永远不会做任何会触发Entity Framework进行更新的事情。EF会进行更改跟踪,只有当它注意到上下文中的某些内容发生了更改或者您明确告诉它某些内容发生了更改时,才会发布更新之类的内容。你两个都没做


传统上,您会像这里所做的那样从数据库中提取对象,然后使用发布的值修改该对象。这里您只对发布的对象进行了更改,重要的是,它没有附加到您的上下文。您从数据库中提取的对象在您的上下文中永远不会被修改。

请注意,由于您正在使用
Bind
筛选发布的值,保存发布的事件可能会产生意外的副作用。保存后,
绑定中未包含的任何值都将被清除。您永远不应该真正保存发布的实例,即使它是一个实体类。始终从数据库中提取新对象,然后将任何已发布的值映射到该对象。
// GET: Events/Edit/5
public ActionResult Edit(int? id)
{
    if (id == null)
    {
        return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
    }

    Event @event = db.Events.Find(id);

    //Image
    @event = db.Events.Include(s => s.Files).SingleOrDefault(s => s.EventID == id);

    //Owner ID
    ViewBag.OID = @event.OwnerID;

    if (@event == null)
    {
        return HttpNotFound();
    }
    ViewBag.VenueID = new SelectList(db.Venues, "VenueID", "OwnerId", @event.VenueID);


    return View(@event);
}

// POST: Events/Edit/5
// To protect from overposting attacks, please enable the specific properties you want to bind to, for 
// more details see http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit([Bind(Include = "EventID,OwnerID,VenueID,EventTitle,EventDate,EventTime,EventDescription,EventCategory,EventYouTube,EventSoundCloud,EventFacebook,EventTwitter,EventInstagram,EventWebsite,EventTicketPrice,EventTicketStore")] Event @event, HttpPostedFileBase upload)
{
    if (ModelState.IsValid)
    {
        Event oldEvent = db.Events.Find(@event.EventID);

        @event.Venue = oldEvent.Venue;
        @event.VenueID = oldEvent.VenueID;
        @event.Files = oldEvent.Files;

        //Image
        if (upload != null && upload.ContentLength > 0)
        {
            if (@event.Files.Any(f => f.FileType == FileType.EventImage))
            {
                db.Files.Remove(@event.Files.First(f => f.FileType == FileType.EventImage));
            }
            var img = new File
            {
                FileName = System.IO.Path.GetFileName(upload.FileName),
                FileType = FileType.EventImage,
                ContentType = upload.ContentType
            };
            using (var reader = new System.IO.BinaryReader(upload.InputStream))
            {
                img.Content = reader.ReadBytes(upload.ContentLength);
            }
            @event.Files = new List<File> { img };
        }

        db.SaveChanges();
        return RedirectToAction("Details", "Events", @event.EventID);
    }
    ViewBag.VenueID = new SelectList(db.Venues, "VenueID", "OwnerId", @event.VenueID);
    return View(@event);
}
EventCategory: Music
    EventDate: {05/11/2016 0:00:00}
    EventDescription: "desc edit"
    EventFacebook: null
    EventID: 40
    EventInstagram: null
    EventSoundCloud: "sc edit"
    EventTicketPrice: null
    EventTicketStore: null
    EventTime: {11/11/2016 22:00:00}
    EventTitle: "t edit"
    EventTwitter: null
    EventWebsite: null
    EventYouTube: "yt edit"
    Files: Count = 1
    OwnerID: "0f1c143f-323a-4e78-9489-89e451f7f30c"
    Venue: {System.Data.Entity.DynamicProxies.Venue_50A507AAD42F98D777DFCA0F94D77A0D914DD5D61DBECA66C53CA7450EAC1B1A}
    VenueID: 15