2016-11-11 74 views
-1

我遇到了我的编辑方法对于我的事件模型的问题,我注意到我所做的更改并未保存到数据库,即使它似乎在代码中工作(I已经通过了断点,所有的线都在执行),我有一种感觉,也许外键导致了一些问题,但我不确定。编辑方法无法使用外键

这是我使用的模型:

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

这是控制器的方法:

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

注:当执行db.SaveChanges出现型号如下 -

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 

这正确反映了我在编辑视图中所做的更改,但这些更改不会似乎改变了我的分贝。

我还注意到,这种方法完成后,始终跳转到Dispose方法前要详细方法

回答

0

尝试 db.Entry(@event).State = EntryState.Modified 然后保存更改

+0

请注意,由于您使用'Bind'来过滤发布的值,因此保存发布的事件可能会产生意想不到的副作用。保存后,任何未包含在“绑定”中的值都将被清除。即使它是一个实体类,也不应该真正保存发布的实例。始终从数据库中提取新对象,然后映射到* that *对象上的任何已发布值。 –

0

你永远不要做任何事情,会触发实体框架进行更新。如果EF注意到上下文中的某些内容发生了变化,或者您已明确告诉它某些内容发生了变化,EF确实会更改跟踪并仅发布类似UPDATE的内容。你既没有做过。

传统上,您可以像在此处所做的那样从数据库中提取对象,然后使用发布的值修改该对象。在这里,您只对发布的对象进行了更改,重要的是,它并未附加到您的上下文。您从数据库中提取的对象和,在您的上下文中从不修改。