Witam,
Rozwijam swoją aplikację bazodanową w ASP.NET MVC3. W dużym skrócie, chodzi o wypożyczanie książek. Książka może być wypożyczona lub nie. Jeśli jest wypożyczona nie można zrobić tego ponownie (działa walidacja). Poniższy model skutecznie pobiera z obcej tabeli (książka) informację o tym czy jest wypożyczona i jeśli tak informuje o błędzie.
To już działa, tyle że mam ręcznie wpisane w bazie, że isAvailable = false. Teraz pracuje nad tym by było to interaktywne tzn. aby po wypożyczniu pole w tabeli isAvailable = true.
Problem:
W jaki sposób zaktualizować informację po dodaniu nowego wypożyczenia o statusie książki tzn. aby nie mogły ją wypożyczyć dwie osoby na raz?
Czy jest jakaś funkcja, która zawsze wykonuje się po zmodyfikowaniu wiersza tabeli, bo jakoś nie znalazłem jej w dokumentacji.
Chcę po prostu ustawić na true wartość kolumny IsAvailable po dodaniu nowego wpisu do tabeli Hire.
Stworzyłem następujący model:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.ComponentModel.DataAnnotations;
namespace Firmowa.Models.HireModels
{
public class Hire : IValidatableObject
{
private BookContext context = new BookContext();
public int HireID { get; set; }
[Required(ErrorMessage = "Czytelnik jest wymagany!")]
[Display(Name = "Czytelnik")]
public int ReaderID { get; set; }
[Required(ErrorMessage = "Książka jest wymagana!")]
[Display(Name = "Książka")]
public int BookID { get; set; }
public DateTime HireDate { get; set; }
public DateTime? ReturnDate { get; set; }
[Display(Name = "Data zwrotu")]
[Required(ErrorMessage = "Data zwrotu jest wymagana!")]
public DateTime DeadlineDate { get; set; }
public virtual Reader Reader { get; set; }
public virtual Book Book { get; set; }
public Hire()
{
this.HireDate = DateTime.Now;
}
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
List<ValidationResult> errors = new List<ValidationResult>();
if(DeadlineDate <= HireDate)
errors.Add(new ValidationResult("Termin zwrotu musi być wcześniej niż termin wypożyczenia!"));
// check whether book is hired
var row = context.Books.SingleOrDefault(r => r.BookID == this.BookID);
if (!row.IsAvailable)
errors.Add(new ValidationResult("Książka jest już wypożyczona!"));
return errors;
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.ComponentModel.DataAnnotations;
namespace Firmowa.Models.HireModels
{
public class Book : IValidatableObject
{
public int BookID { get; set; }
[Required(ErrorMessage = "Tytuł jest wymagany")]
[Display(Name = "Tytuł")]
public string Title { get; set; }
[Required(ErrorMessage = "ISBN jest wymagany")]
public string ISBN { get; set; }
[Required(ErrorMessage = "Autor jest wymagany")]
[Display(Name = "Autor")]
public int AuthorID { get; set; }
[Display(Name = "Rok")]
[Required(ErrorMessage = "Rok jest wymagany")]
public uint year { get; set; }
[Display(Name = "Wydawca")]
[Required(ErrorMessage = "Wydawca jest wymagany")]
public int PublisherID { get; set; }
[Display(Name = "Kategoria")]
[Required(ErrorMessage = "Kategoria jest wymagana")]
public int CategoryID { get; set; }
public bool IsAvailable { get; set; }
public virtual Author Author { get; set; }
public virtual Publisher Publisher { get; set; }
public virtual Category Category { get; set; }
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
List<ValidationResult> errors = new List<ValidationResult>();
if (year > 2050 || year < 1910)
{
errors.Add(new ValidationResult("Nieprawidłowy rok"));
}
return errors;
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Data.Entity;
using System.Data.Entity.ModelConfiguration.Conventions;
using Firmowa.Models;
using Firmowa.Models.HireModels;
using Firmowa.Models.HireModels.DAL;
namespace Firmowa.Models.HireModels
{
public class BookContext : DbContext
{
public DbSet<Author> Authors { get; set; }
public DbSet<Book> Books { get; set; }
public DbSet<Category> Categories { get; set; }
public DbSet<Publisher> Publishers { get; set; }
public DbSet<Reader> Readers { get; set; }
public DbSet<Hire> Hires { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
modelBuilder.Entity<Book>().HasRequired(x => x.Author);
modelBuilder.Entity<Book>().HasRequired(x => x.Category);
modelBuilder.Entity<Book>().HasRequired(x => x.Publisher);
modelBuilder.Entity<Hire>().HasRequired(x => x.Book);
modelBuilder.Entity<Hire>().HasRequired(x => x.Reader);
}
}
}
Próbowałem użyć następującego kodu konstruktora tabeli Hire:
<code class="c#">
public Hire()
{
this.HireDate = DateTime.Now;
// mark book as hired
var query = from r in context.Books where r.BookID == this.BookID select r;
foreach (Book r in query)
{
r.IsAvailable = false;
}
// submit the changes to the database
context.SaveChanges();
}
To nie działa. Wartość isAvailable wciąż pozostaje true i można wypożyczyć pozycję jeszcze raz.
Pozdrawiam,