Как избежать извлечения реляционных объектов в цикле реляционных ссылок с использованием Entity Framework? - PullRequest
0 голосов
/ 19 марта 2019

Я пытаюсь правильно спроектировать структуру метода контроллера Api со следующим объектом в качестве возвращаемого типа:

           var obj= new CustomObject
                    {
                        Id = a.Id,
                        stampleProperty= a.stampleProperty,
                        stampleProperty= a.stampleProperty2,
                        B= a.B,
                    };

Базовый сценарий состоит из двух объектов A и B, которые имеют «Многодля многих », как описано ниже:

enter image description here

public class A
{

   public int AId { get; set; }
   public string sampleProperty{ get; set; }        
   public string sampleProperty2{ get; set; }

   public virtual ICollection B { get; set; }
}

public class B
{

   public int BId { get; set; }
   public string sampleProperty3{ get; set; }        
   public string sampleProperty4{ get; set; }
   public int  ComyId { get; set; }

   public virtual ICollection A{ get; set; }
   public virtual Comy Comy{ get; set; }
}

Примечание: Я не могу изменить структуру базы данных.Кроме того, я ищу наилучший из возможных способов получения реляционных объектов B из объекта A, без виртуальных свойств B для A.

Код, который я пробовал на контроллере, хотя он использует подход "LazyLoading", возвращаетвстроенные объекты типа A в каждом связанном объекте типа B.

var a = db.A.FirstOrDefault(a => a.stampleProperty== stampleProperty);
var obj= new CustomObject
                    {
                        Id = a.AId,
                        sampleProperty= a.sampleProperty,
                        sampleProp= a.sampleProp,
                        B = a.B,
                    };

Возврат:

{
 "AId": 
 "sampleProperty":
 "sampleProp":
 "B":[{
      "BId":
      "sampleProperty3":
      "sampleProperty4":
      "ComyId":
      "A":[ **REFERENCE LOOP**  ]
      "ComyId":
      "Comy":{}
     }]
}

Цель: B объектов без виртуальных свойств A.

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

1 Ответ

0 голосов
/ 16 апреля 2019

Я бы предложил создать дополнительный пользовательский объект и сопоставить поля (либо вручную, либо с использованием инфраструктуры, такой как AutoMapper).

Применительно к вашему примеру это может выглядеть примерно так:

public class CustomObjectA
{
    public int Id { get; set; }
    public string stampleProperty { get; set; }
    public string stampleProperty2 { get; set; }
    public CusomObjectB[] B { get; set; }
}

public class CustomObjectB
{
    public int BId { get; set; }
    public string sampleProperty3{ get; set; }        
    public string sampleProperty4{ get; set; }
    public int ComyId { get; set; }
}

И использование будет выглядеть так:

var a = db.A.FirstOrDefault(a => a.stampleProperty== stampleProperty);

var obj= new CustomObjectA
{
    Id = a.AId,
    sampleProperty= a.sampleProperty,
    sampleProp= a.sampleProp,
    B = a.B.Select(b => new CustomObjectB
    {
        BId = b.BId,
        sampleProperty3 = b.sampleProperty3

        //etc...
    }).ToArray()
};

Не обязательно хорошая идея возвращать объекты базы данных прямо из API по этим причинам (наряду с некоторыми другими, например, если вы не хотите, чтобы третьи стороны, использующие ваш API, могли видеть каждое свойство в базе данных) .

Общим термином для этого подхода является использование DTO (объектов передачи данных). Вот учебник от Microsoft, где они обсуждают его дальше https://docs.microsoft.com/en-us/aspnet/web-api/overview/data/using-web-api-with-entity-framework/part-5.

...