Внешние ключи связанных данных Entity Framework - PullRequest
0 голосов
/ 12 декабря 2018

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

 DeliverNote
     Adress add1 {get; set;}
     Adress add2 {get; set;} 

Я могу нормально загружать адреса сами по себе, но не могу загрузить DeliveryNote, потому что EF, по-моему, не загружает связанные данные по умолчанию.Поэтому я нашел решения, в основном с context.notes.Include (dn => dn.Adresses), но я просто не могу понять, как я сообщаю заметке или классу адресов, как они связаны друг с другом.В основном, когда я набираю «дн».ничего не появляется.

Самое простое, вероятно, работающее решение, которое я видел, было от Microsoft.В github с этой страницы https://docs.microsoft.com/de-de/ef/core/querying/related-data вы можете увидеть классы Blog и Post.Для меня класс Post выглядит некорректно, но почему Post должен знать о блоге, в котором он находится?Это также испортит базу данных в первых решениях кода.Что, если одно и то же сообщение будет опубликовано в нескольких блогах?

Большинство решений также выглядят как списки, у меня нет списка, только простые отдельные объекты.1-1 отношения, я думаю.

Ответы [ 2 ]

0 голосов
/ 13 декабря 2018

Итак, у вас есть база данных с таблицей Addresses и таблицей DeliveryNotes.Каждый DeliveryNote имеет два внешних ключа для Addresses: один From и один To (вы называете это addr1 и addr2)

Если вы следуете первым соглашениям кода платформы сущностей , у вас будет что-то вроде этого:

class Address
{
     public int Id {get; set;}
     ... // other properties

     // every Address has sent zero or more delivery Notes (one-to-many)
     public virtual ICollection<DeliveryNote> SentNotes {get; set};

     // every Address has received zero or more delivery Notes (one-to-many)
     public virtual ICollection<DeliveryNote> ReceivedNotes {get; set};
}

class DeliveryNote
{
     public int Id {get; set;}
     ... // other properties

     // every DeliveryNote comes from an Address, using foreign key
     public int FromId {get; set;}
     public virtual Address FromAddress {get; set;}

     // every DeliverNote is sent to an Address, using foreign key:
     public int ToId {get; set;}
     public virtual Address ToAddress {get; set;}
}

В каркасе сущностей столбцы таблиц представлены не виртуальными свойствами.Виртуальные свойства представляют отношения между таблицами.

Обратите внимание, что ICollection и FromAddress / ToAddress являются виртуальными и, следовательно, не являются столбцами в ваших столбцах.При желании вы можете оставить их вне своих классов.Однако, если у вас есть эти виртуальные свойства, вам не нужно выполнять (Групповые) объединения самостоятельно.

Я могу загружать адреса сами по себе, но не могу загрузить DeliveryNote,потому что EF не загружает связанные данные по умолчанию ... I

Из этого нелегко определить, какой тип запросов вы хотите.

Одна из более медленных частейзапросов к базе данных - это транспортировка выбранных данных из вашей СУБД в локальный процесс.Следовательно, разумно минимизировать передаваемые данные.

Если вы используете Include, тогда весь объект переносится, включая внешние ключи и все свойства, которые вам не нужны.Если у вас есть база данных со школами и учениками, то у каждого учащегося будет ключ от школы, которую он посещает.Если вы запрашиваете «Школа со своими 1000 учениками» школы с идентификатором 4 с помощью «Включить», вы не хотите переносить внешний ключ SchoolId 1000 раз, поскольку вы уже знаете, что он будет иметь значение 4

* 1030.*

В каркасе сущностей используйте «Включить», только если вы хотите изменить / обновить выбранный элемент, в противном случае используйте «Выбрать»

. Учитывая кучу DeliveryNotes, дайте мне несколько AddressDetails:1036 *

IQueryable<DeliveryNote> deliveryNotes = dbContext.DeliveryNotes
   .Where (deliveryNote => ...) // probably something with Id, or Date, or subject
   .Select(deliveryNote => new
   {
       // select only the delivery note properties you actually plan to use
       Subject = deliveryNote.Subject,
       DeliveryDate = deliveryNote.DeliveryDate,
       ...

       From = new
       {
           // select only the From properties you plan to use
           Id = deliveryNote.FromAddress.Id,
           Name = deliveryNote.FromAddress.Name,
           Address = deliveryNote.FromAddress.Address,
           ...
       }

       To = new
       {
            // again: only properties you'll use
            Name = deliveryNote.ToAddress.Name,
            ...
       },
   });

Платформа сущностей знает отношение один-ко-многим и выполнит для вас правильное объединение.

Учитывая несколько адресов, дайте мне некоторые DeliveryNotesони получили

var query = dbContext.Addresses
    .Where(address => address.City == "New York" && ...)
    .Select(address => new
    {
         // only properties you plan to use
         Id = address.Id,
         Name = address.Name,

         ReceivedNotes = address.ReceivedNotes
             .Where(note => note.DeliveryDate.Year == 2018)
             .Select(note => new
             {
                 // only properties you plan to use:
                 Title = note.Title,
                 ...

                 // no need for this, you know it equals Id
                 // AddressId = note.FromId,
             }),
    });

Структура сущности знает отношение один-ко-многим и будет выполнять правильное групповое соединение для вас.

Если у вас есть один-к-одномумного отношений, и вы хотите, чтобы «элемент с его многочисленными подпунктами», начните с одной стороны и используйте виртуальную коллекцию ICollection.Если вы хотите подчиненный элемент с элементом, которому он принадлежит, начните с многогранника и используйте виртуальное свойство с односторонней

0 голосов
/ 12 декабря 2018

Если вы определите свою модель как:

public class DeliverNote {
    public int Id { get; set; }
    public Adress addr1 { get; set; }
    public Adress addr2 { get; set; }
}

public class Adress {
    public int Id { get; set; }
}

Затем вы можете позвонить:

context.notes.Include(dn => dn.addr1).Include(dn => dn.addr2);

, которая будет включать соответствующие данные.

Ваша модель не '• определить внешние ключи для addr1 или addr2, поэтому EF Core создаст для вас теневые свойства, то есть столбцы, которые существуют в таблице, но не являются свойствами в модели c #.

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