Linq2 SQL Выполняет несколько запросов для дочерних коллекций, несмотря на DataLoadOptions и Projection - PullRequest
0 голосов
/ 16 июня 2020

Я работаю над устаревшим проектом с ASP. NET MVC (старая версия) и Linq2 SQL среди других технологий.

У меня проблемы с бизнес-объектом, который имеет следующую структуру:

Заказ

  • Имеет ссылку на родительский объект DocumentType
  • Имеет ссылку на родительский объект DocumentSubtype
  • Имеет ссылку на родительский объект Customer
  • Имеет ссылку на родительский объект DocumentStatus
  • Имеет ссылку на родительский объект aspnet_User (CreationUser)
  • Имеет ссылку на родительский объект aspnet_User (ModificationUser)
  • Имеет коллекцию OrderDetails
  • Имеет коллекцию OrderDiscounts
  • Имеет коллекцию OrderTrackings

Это часть кода, сгенерированного Linq2 SQL:

[global::System.Data.Linq.Mapping.TableAttribute(Name="dbo.[ORDER]")]
public partial class ORDER : INotifyPropertyChanging, INotifyPropertyChanged
{

    private static PropertyChangingEventArgs emptyChangingEventArgs = new PropertyChangingEventArgs(String.Empty);

    private int _OrderID;

    private byte _DocumentTypeID;

    private short _DocumentSubtypeID;

    private byte _BusinessUnitID;

    private string _CustomerID;

    private string _AddressCodeID;

    private string _SalesPersonID;

    private string _SaleConditionID;

    private System.Nullable<System.DateTime> _ShippedDate;

    private string _PurchaseOrder;

    private string _OrderComment;

    private byte _State;

    private string _OrderIDGp;

    private System.Nullable<int> _ErrorCode;

    private string _ErrorDesc;

    private System.Nullable<System.DateTime> _DateAdd;

    private string _BatchName;

    private System.Nullable<System.Guid> _CreationUserID;

    private System.Nullable<System.DateTime> _CreationDate;

    private System.Nullable<System.Guid> _ModificationUserID;

    private System.Nullable<System.DateTime> _ModificationDate;

    private System.Nullable<int> _BatchOwner;

    private bool _Multiline;

    private System.Nullable<System.Guid> _DeletionUserID;

    private System.Nullable<System.DateTime> _DeletionDate;

    private EntitySet<ORDER_DETAIL> _ORDER_DETAILs;

    private EntitySet<ORDER_TRACKING> _ORDER_TRACKINGs;

    private EntitySet<ORDER_DISCOUNT> _ORDER_DISCOUNTs;

    private EntityRef<aspnet_User> _aspnet_User;

    private EntityRef<aspnet_User> _aspnet_User1;

    private EntityRef<CUSTOMER> _CUSTOMER;

    private EntityRef<DocumentStatus> _DocumentStatus;

    private EntityRef<DocumentType> _DocumentType;

    private EntityRef<DocumentSubtype> _DocumentSubtype;

public ORDER()
    {
        this._ORDER_DETAILs = new EntitySet<ORDER_DETAIL>(new Action<ORDER_DETAIL>(this.attach_ORDER_DETAILs), new Action<ORDER_DETAIL>(this.detach_ORDER_DETAILs));
        this._ORDER_TRACKINGs = new EntitySet<ORDER_TRACKING>(new Action<ORDER_TRACKING>(this.attach_ORDER_TRACKINGs), new Action<ORDER_TRACKING>(this.detach_ORDER_TRACKINGs));
        this._ORDER_DISCOUNTs = new EntitySet<ORDER_DISCOUNT>(new Action<ORDER_DISCOUNT>(this.attach_ORDER_DISCOUNTs), new Action<ORDER_DISCOUNT>(this.detach_ORDER_DISCOUNTs));
        this._aspnet_User = default(EntityRef<aspnet_User>);
        this._aspnet_User1 = default(EntityRef<aspnet_User>);
        this._CUSTOMER = default(EntityRef<CUSTOMER>);
        this._DocumentStatus = default(EntityRef<DocumentStatus>);
        this._DocumentType = default(EntityRef<DocumentType>);
        this._DocumentSubtype = default(EntityRef<DocumentSubtype>);
        OnCreated();
    }

Я пытаюсь выполнить этот метод из класса обслуживания, чтобы получить все данные в единый запрос. Чтобы добиться этого, я сначала пробовал использовать DataLoadOptions перед тем, как вводить контекст в класс Repository, но Linq2 SQL продолжал генерировать один запрос для каждого дочернего элемента в коллекциях. Затем я перешел к проекциям, как я видел во многих руководствах, это репозиторий, измененный с помощью этой опции:

        public IEnumerable<ORDER> GetAll(Expression<Func<ORDER, bool>> filter = null)
    {
        var query = _dbContext
                        .ORDERs
                        .AsQueryable();

        if (filter != null)
            query = query.Where(filter);

        return query
                .Select
                (
                    x => new OrderEntity
                    {
                        OrderID = x.OrderID,
                        DocumentTypeID = x.DocumentTypeID,
                        BusinessUnitID = x.BusinessUnitID,
                        DocumentSubtypeID = x.DocumentSubtypeID,
                        SalesPersonID = x.SalesPersonID,
                        PurchaseOrder = x.PurchaseOrder,
                        SaleConditionID = x.SaleConditionID,
                        CustomerID = x.CustomerID,
                        AddressCodeID = x.AddressCodeID,
                        ShippedDate = x.ShippedDate,
                        OrderComment = x.OrderComment,
                        BatchOwner = x.BatchOwner,
                        Multiline = x.Multiline,
                        State = x.State,
                        OrderIDGp = x.OrderIDGp,
                        BatchName = x.BatchName,
                        ErrorCode = x.ErrorCode,
                        ErrorDesc = x.ErrorDesc,
                        DateAdd = x.DateAdd,
                        CreationUserId = x.CreationUserId,
                        CreationDate = x.CreationDate,
                        ModificationUserId = x.CreationUserId,
                        ModificationDate = x.ModificationDate,
                        DeletionUserId = x.DeletionUserId,
                        DeletionDate = x.DeletionDate,
                        DocumentType = x.DocumentType,
                        DocumentSubtype = x.DocumentSubtype,
                        CUSTOMER = x.CUSTOMER,
                        ORDER_DETAILs = x.ORDER_DETAILs,
                        ORDER_DISCOUNTs = x.ORDER_DISCOUNTs,
                        ORDER_TRACKINGs = x.ORDER_TRACKINGs,
                        DocumentStatus = x.DocumentStatus
                    }
                )
                .ToList();
    }

Вот скриншот из SQL Profiler, когда я запускаю вышеуказанный метод:

enter image description here

Он продолжает генерировать одни и те же последние 3 запроса для каждой записи, которая соответствует критериям фильтра. OrderDetails является частью основного запроса, но я не могу сделать то же самое с OrderDiscounts и OrderTrackings. Я хотел бы избежать обновления до Entity Framework из-за нехватки времени, поэтому будет приветствоваться любая помощь с этим.

Спасибо.

...