编辑方法无法使用外键

时间:2016-11-11 14:43:42

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

我遇到了我的事件模型编辑方法的问题,我注意到我所做的更改并没有保存到数据库,即使它似乎在代码中工作(我已经介入了断点和所有线条正在执行),我有一种感觉,也许外键引起了一些问题,但我不确定。

这是我正在使用的模型:

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方法,然后再转到详细信息方法

2 个答案:

答案 0 :(得分:0)

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

答案 1 :(得分:0)

您不会做任何会触发Entity Framework进行更新的事情。 EF确实会改变跟踪,只有在注意到上下文中的某些内容发生了变化或者您已明确告知某些内容已发生变化时,才会发出类似UPDATE的内容。你们两个都没做过。

传统上,您可以像在此处一样从数据库中提取对象,然后使用已发布的值修改该对象。在这里,您只对发布的对象进行了更改,这一点很重要,不会附加到您的上下文中。从数据库中提取的对象和上下文中 的对象永远不会被修改。