Загрузка списка данных, который ссылается на связанные данные в другой таблице - PullRequest
1 голос
/ 24 января 2020

решено

Я пытаюсь выяснить, как я могу получить набор связанных данных из таблицы в рамках сущностей, но я еще не решил ее.

Это соотношение многих ко многим между двумя таблицами, как показано на рисунке ниже:

enter image description here enter image description here

Моя проблема заключается в том, что я хочу получить связанные книги для автора, который представляет собой ICollection таблицы BOOK, но вместо этого при возврате мне выдает пустой список. Я попытался решить эту проблему с помощью явной загрузки:

public AUTHOR Read(int Aid)
{
    using(var db = new LibraryDBEntities1())
    {
        var author = db.AUTHORs.Find(Aid);
        db.Entry(author).Collection(a => a.BOOKs).Load();

        return author;
    }
}

Я также попытался увеличить ее, используя готовую загрузку

return db.AUTHORs.Where(a => a.Aid == Aid).Include("BOOKs").FirstOrDefault();

, но она также не работала. Я пытался следовать документации по Microsoft Docs Загрузка связанных объектов , но я не смог понять, что я делаю неправильно. Может кто-нибудь помочь мне с этой проблемой и, возможно, объяснить, где я делаю неправильно?

РЕДАКТИРОВАТЬ 1 Так выглядит OnModelCreating. Должен ли я изменить / добавить код здесь? Я использую подход Database First.


protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    throw new UnintentionalCodeFirstException();
}

EDIT 2

Соединение базы данных должно выглядеть следующим образом:

enter image description here

РЕДАКТИРОВАТЬ 3

Я забыл упомянуть, что я использую 3-уровневую архитектуру, включая уровень представления (MVC) уровень бизнес-логики c и уровень доступа к данным. А также слой данных, который включает в себя базу данных, как показано на рисунке ниже.

enter image description here

РЕШЕНИЕ

Так что я наконец-то решил это! Так что проблема была не совсем той, о которой я сначала подумал, а скорее из-за того, как я использую свой Mapper. Мне пришлось добавить следующий код в мою модель, чтобы заставить его работать:

authorObj.BooksList = Mapper.Map<List<BOOK>, List<Book>>(aauthor.BOOKs.ToList());

Теперь все работает как надо!

Ответы [ 2 ]

0 голосов
/ 24 января 2020

EF 6 включает соглашения по умолчанию для отношений «многие ко многим». Вы должны включить свойство навигации коллекции на обоих концах. Таким образом, ваши определения класса модели абсолютно хороши. Вам следует обновить OnMOdalCreating, как показано ниже;

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    base.OnModelCreating(modelBuilder);
}

Затем вы можете использовать его, как показано ниже;

return db.AUTHORs.Where(a => a.Aid == Aid).Include(a => a.BOOKs).FirstOrDefault();

PS: я настоятельно рекомендую вам создать класс модели для тип соединения.

EDIT При первом подходе к базе данных вам необходимо создать класс модели для каждой таблицы в базе данных.

Так что не меняйте свой OnMOdalCreating метод. Добавьте новый класс, как показано ниже;

[Table("BOOK_AUTHOR")]
public class BookAuthor
{
    public int ISBN { get; set; }
    public int AId { get; set; }
    public virtual Book Book { get; set; }
    public virtual Author Author { get; set; }
}

, затем вам нужно привязать свойства к свойствам первичного ключа через атрибуты или API-интерфейс FLuent. После этого вы сможете получить автора с книгами, как показано ниже

var authorWithBooks = context.Authors
    .Include(a => a.BookAuthors.Select(ba => ba.Book))
    .Where(...)
    .ToList();
0 голосов
/ 24 января 2020

Так как, это первый подход к базе данных, попробуйте добавить приведенное ниже отображение к вашей OnModelCreating функции

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
     base.OnModelCreating(modelBuilder);

     modelBuilder.Entity<BOOKs>()
        .HasMany<AUTHORs>(b => b.AUTHORs)
        .WithMany(a => a.BOOKs)
        .Map(m => m.ToTable("BOOK_AUTHOR")
        .MapLeftKey("ISBN")
        .MapRightKey("Aid"));

// or like below
       /* modelBuilder.Entity<BOOKs>()
         .HasMany<AUTHORs>(s => s.AUTHORs)
         .WithMany(c => c.BOOKs)
         .Map(cs =>
         {
              cs.MapLeftKey("ISBN");
              cs.MapRightKey("Aid");
              cs.ToTable("BOOK_AUTHOR"); // Use the correct junction table name here. and correct key names
         });*/
    }

Также удалите оператор, который выдает исключение.

И затем используйте:

db.AUTHORs.Include("BOOKs").Where(a => a.Aid == Aid).FirstOrDefault();

или

db.AUTHORs.Include(a => a.BOOKs).Where(a => a.Aid == Aid).FirstOrDefault();

или просто напрямую иметь предикат в FirstOrDefault без предложения WHERE.

db.AUTHORs.Include(a => a.BOOKs).FirstOrDefault(a => a.Aid == Aid); // Same as above two queries.

ОБНОВЛЕНИЕ :

var query = db.AUTHORs.Include(a => a.BOOKs).Where(a => a.Aid == Aid);
var firstBook = query.FirstOrDefault(); // Have a break point here. Please see what is in query via quick watch.

При быстром просмотре запроса (не firstBook) вы должны увидеть Sql, как показано ниже:

enter image description here

Пожалуйста, примите это SQL и отправьте свои наблюдения здесь после выполнения непосредственно в SSMS, например

  • , видите ли вы соединение с BOOK в запросе или нет
  • и содержит ли набор результатов столбцы из КНИГИ.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...