Здравствуйте всем. Помогите мне, пожалуйста, разобраться наконец-то с добавлением записей в БД при отношении один-ко-многим и многие-ко-многим. Использую технологию Entity Framework, подход проектирования приложения Model-First, не использую паттерн MVVM. Заранее прошу прощения за такой длинный пост и прошу вас отнестись к этому вопросу серьёзно, поскольку я на этот вопрос потратил 2 недели и до сих пор не могу решить этот вопрос из-за того, что нет нигде нормального адекватного источника информации о том, как же всё-таки правильно выполнять CRUD операции.
Вопросы:
Внизу предоставлена моя модель приложения:
Внизу предоставлены сгенерированные автоматически классы после сохранения созданной модели при Model-First проектировании:
public partial class Catalog
{
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
public Catalog()
{
this.Books = new HashSet<Book>();
}
public System.Guid Id { get; set; }
public string Name { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<Book> Books { get; set; }
}
public partial class Book
{
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
public Book()
{
this.Orders = new HashSet<Order>();
}
public System.Guid Id { get; set; }
public string Name { get; set; }
public string Genre { get; set; }
public string Author { get; set; }
public short Year { get; set; }
public virtual Catalog Catalog { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<Order> Orders { get; set; }
}
public partial class Order
{
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
public Order()
{
this.Books = new HashSet<Book>();
}
public System.Guid Id { get; set; }
public string Number { get; set; }
public Nullable<System.DateTime> RegisteredOn { get; set; }
public Nullable<System.DateTime> ClosureDate { get; set; }
public virtual Reader Reader { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<Book> Books { get; set; }
}
public partial class LibraryModelContainer : DbContext
{
public LibraryModelContainer()
: base("name=LibraryModelContainer")
{
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
throw new UnintentionalCodeFirstException();
}
public virtual DbSet<Book> Books { get; set; }
public virtual DbSet<Catalog> Catalogs { get; set; }
public virtual DbSet<Order> Orders { get; set; }
public virtual DbSet<Reader> Readers { get; set; }
}
Теперь нужно оговориться, что я в своём приложении в отдельных окнах осуществляю добавление записей в БД. Также я не показываю всю свою логику по добавлению записи, чтобы максимально сократить свой пост, показываю только основную часть.
Отношение между сущностями Каталог и Книга — один-ко-многим
1. Добавление каталога в БД:
using (LibraryModelContainer dbContainer = new LibraryModelContainer())
{
Catalog catalog = new Catalog
{
Id = Guid.NewGuid(),
Name = CatalogTextBox.Text
};
dbContainer.Catalogs.Add(catalog);
dbContainer.SaveChanges();
}
2. Добавление книги в БД:
using (LibraryModelContainer dbContainer = new LibraryModelContainer())
{
Catalog catalog = dbContainer.Catalogs.Find(((Catalog)BookCatalogComboBox.SelectedItem).Id);
Book book = new Book
{
Id = Guid.NewGuid(),
Name = BookAuthorTextBox.Text,
Genre = BookGenreComboBox.Text,
Author = BookAuthorTextBox.Text,
Year = Convert.ToInt16(BookYearMaskedTextBox.Text),
Catalog = catalog
};
dbContainer.Books.Add(book);
dbContainer.SaveChanges();
_window.BookDataGrid.ItemsSource = dbContainer.Books.ToList();
}
Отношение между сущностями Книга и Заказ — многие-ко-многим
1. Добавление книги в БД:
Пример показал выше!
2. Добавление заказа в БД:
using (LibraryModelContainer dbContainer = new LibraryModelContainer())
{
Reader reader = dbContainer.Readers.Find(((Reader)ReaderNameComboBox.SelectedItem).Id);
ICollection<Book> books = new List<Book>();
foreach (Book book in BasketBookDataGrid.Items)
{
books.Add(book);
}
Order order = new Order
{
Id = Guid.NewGuid(),
Number = "НОМЕР123",
RegisteredOn = DateTime.Now,
ClosureDate = null,
Reader = reader,
Books = books
};
dbContainer.Orders.Add(order);
dbContainer.SaveChanges();
_window.OrderDataGrid.ItemsSource = dbContainer.Orders.ToList();
}
Тут нужно оговориться, что у меня в окне есть BasketDataGrid. Отдельной таблицы в БД под неё нет. Код BasketGrid в XAML разметке:
<DataGrid Name="BookDataGrid">
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding Name}" Header="Название" MinWidth="114"></DataGridTextColumn>
<DataGridTextColumn Binding="{Binding Genre}" Header="Жанр" MinWidth="114"></DataGridTextColumn>
<DataGridTextColumn Binding="{Binding Author}" Header="Автор" MinWidth="114"></DataGridTextColumn>
<DataGridTextColumn Binding="{Binding Year}" Header="Год издания" MinWidth="114"></DataGridTextColumn>
</DataGrid.Columns>
</DataGrid>
Метод добавления книг в BasketDataGrid:
private void AddBookToTheBasket_Click(object sender, RoutedEventArgs e) // Добавление книг в корзину заказа
{
using (LibraryModelContainer dbContainer = new LibraryModelContainer())
{
Book book = dbContainer.Books.Find(((Book)BookDataGrid.SelectedItem).Id);
if (book != null) // Если в DataGrid книг выбрана строка
{
BasketBookDataGrid.Items.Add(book);
}
else // Если в DataGrid книг ничего не выбрано
{
MessageBox.Show("В таблице книг не выбрана книга.");
}
}
}
Собственно говоря, когда пытаюсь осуществить добавление записей в отношении к сущностям многие-ко-многим, у меня возникает такая ошибка:
Не совсем понятно, при чём тут название ассоциации CatalogBook в моей модели и почему VS на неё ругается. Добавление записей в отношение один-ко-многим у меня корректно происходит, возможно я не прав, лучше поправьте меня, если ошибаюсь. Но тем не менее в БД в плане ID всё хорошо у меня:
Но, меня настораживает одно: в отладчике, когда смотрю на свойства объектов книги, почему-то свойство Catalog имеет значение null, но такого быть не может вообще, поскольку при добавлении в отношении один-ко-многим я это на 100% проверил и там всё хорошо. Вот скриншот объекта книги, где я синим цветом обвёл свойство Catalog.
Виртуальный выделенный сервер (VDS) становится отличным выбором
Использую базу данных postgres, в ней 10 таблиц и в каждой около миллиона записейВсе таблицы связаны с вызовами и имеют уникальный md5
Подскажите пожалуйстаНужно выбрать с БД MySQL сначало по id, потом по поиску из textbox
Изучая LINQ наткнулся на то, что результат запроса имеет такой тип, но информации по нему найти не удалось