0

I am making an auction application. Currently I am working on the bidding system. My Auction model consists of:

public class Auctions
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int ID { get; set; }
    (...) some more fields like title, description etc(...)
    public List<Bid> bids = new List<Bid>(); // a list of bids from the users
}
public class Bid
{
    public string bidAuthor { get; set; }
    public decimal bid { get; set; }
    public DateTime bidDate { get; set; }
}

In the view, I have a form for sending a bid:

@model BiddingViewModel 
(...)info stuff about the auction(...)
@using (Html.BeginForm("CreateBid", "Auction", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
    @Html.AntiForgeryToken()
    @Html.HiddenFor(model=>model.auctionToSend.ID)
    @Html.EditorFor(model => model.bid)
    <input type="submit" value="Send a bid" />

}

Then, my contoller:

    [Authorize]
    [HttpPost]
    [ValidateAntiForgeryToken]
    public async Task<ActionResult> CreateBid(BiddingViewModel bvm)
    {

        var user = await _userManager.FindByIdAsync(HttpContext.User.GetUserId());
        var tmp = _context.Auctions.FirstOrDefault(i => i.ID == bvm.auctionToSend.ID);
        Bid newBid = new Bid()
        {
            bid = decimal.Parse(bvm.bid.ToString()),
            bidAuthor = user.Email,
            bidDate = DateTime.Now
        };
        tmp.bids.Add(newBid);
        _context.Entry(tmp).State = Microsoft.Data.Entity.EntityState.Modified;
        _context.SaveChanges();
        return RedirectToAction("AuctionList", "Auction");
    }

Unfortunately, this doesn't seem to update my bids column in my database (which is of type VARBINARY(MAX)). What am I doing wrong?

Simon
  • 2,643
  • 3
  • 40
  • 61
  • Did u try to debug your code? Do you have some errors? – Alexandr Aug 20 '16 at 11:16
  • You don't need to set the entity as `EntityState.Modified`, EF will do that for you. – DavidG Aug 20 '16 at 11:17
  • Also, can you show your schema? That last sentence seems to imply `bids` is a column instead of being a table of it's own. Which means you should be getting some really odd errors. – DavidG Aug 20 '16 at 11:18
  • Where is your Bid model? – Alexandr Aug 20 '16 at 11:21
  • 1
    It appears your wanting to add a new `Bid`. In which case you code should be just `_context.Bids.Add(newBid); context.SaveChanges();` although I guessing you should also be setting a property such as `newBid .AuctionsId = bvm.auctionToSend.ID;`. Your use of `decimal.Parse(bvm.bid.ToString())` also seems strange - why isn't the `bid` property of your view model `decimal` in the first place? –  Aug 20 '16 at 11:42
  • @Alexandr I tried to debug it, I don't have any errors, the bid just isn't added. Also, I added Bid model – Simon Aug 20 '16 at 11:47
  • @DavidG yes, I treat `bids` as a column of the table `Auctions` but I am not getting any errors – Simon Aug 20 '16 at 11:49
  • @StephenMuecke I see, aren't you able to do this as I posted in a previous comment? – Simon Aug 20 '16 at 11:50
  • 1
    But `bids` is just a field in your model. It would need to be `public virtual ICollection bids { get; set; }` and `Bid` would need a navigation properties `public int AuctionsId { get; set; }` and `public virtual Auctions Auction { get; set; }` to create the relationships –  Aug 20 '16 at 11:57
  • @StephenMuecke Thank you so much, you saved me a lot of time. I followed your instructions, got many errors on the way, but in the end the bids are now added to a new table - everything seems to be working well. One thing though, can you explain why the virtual fields needed to be added to both `Auctions` and `Bid` models? – Simon Aug 20 '16 at 12:46
  • I have just noticed that you have `bids` as a `VARBINARY(MAX)` max column and didn't realize you didn't have the necessary `Bids` table. EF use `virtual` properties for lazy loading and change tracking (refer [this answer](http://stackoverflow.com/questions/5597760/what-effects-can-the-virtual-keyword-have-in-entity-framework-4-1-poco-code-fi) for an explanation - and its worth reading up a bit more on this) –  Aug 20 '16 at 12:50
  • hey @StephenMuecke , one more question: let's say I want to display the number of bids each auction currently has (the bids are now in a separate table). I can add a field to the model view with calculated count of the bids with auction's id. But is there a faster way of doing that in the view? – Simon Aug 20 '16 at 13:24
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/121444/discussion-between-stephen-muecke-and-simon). –  Aug 21 '16 at 00:41

1 Answers1

0

I'll try to explain this as good as I can for the future users: the problem was that I tried to add the List as a column of the table. What I should have done was to add a new table for the Bids, linked in ApplicationDbContext:

public DbSet<Auctions> Auctions { get; set; }
public DbSet<Bid> Bids { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
   modelBuilder.Entity<Auctions>()
   .HasOne(p => p.Signup)
   .WithMany(b => b.Auction);

   modelBuilder.Entity<Bid>()
   .HasOne(p => p.Auction)
   .WithMany(b => b.bids);

   base.OnModelCreating(modelBuilder);
}

The rest was explained in Stephen Muecke's comments

Simon
  • 2,643
  • 3
  • 40
  • 61