簡體   English   中英

實體框架:如何查詢數據庫中的多個相關表進行單次旅行

[英]Entity Framework: How to query a number of related tables in a database making a single trip

我的查詢目前太慢了。 我正在嘗試在主頁面上搜索代碼(字符串),這將為用戶提供相關信息。 例如。 用戶可以從主頁面搜索代碼,這將在Job,Work Phase,Wbs,Work Element,EA,Jobcard和Estimate中搜索代碼並返回相關信息。 我在數據庫中進行了多次訪問以收集我需要的數據,當我相信它只能在一個數據庫中完成時。 我有許多鏈接的表:合同,工作,工作階段,Wbss,工程活動,Jobcards和估計。 合同有一個Jobs列表,Jobs有一個Workphases列表,Workphases有一個Wbss列表等

有更快的方法嗎?

public Result Handle(Query query)
{                   
    query.Code = query.Code ?? string.Empty;

    var result = new Result();

    //result.SetParametersFromPagedQuery(query);
    result.Items = new List<Item>();

    if (query.SearchPerformed)
    {
        var contracts = _db.Contracts.AsEnumerable().Where(x => x.Code == query.Code);

        result.Items = result.Items.Concat(contracts.Select(x => new Item()
        {
            Code = x.Code,
            Id = x.Id,
            Name = x.Name,
            Type = MainPageSearchEnum.Contract,
            ContractName = x.Name,
            Url = string.Format("Admin/Contract/Edit/{0}", x.Id)
        })).ToList();


        var jobs = _db.Jobs.AsEnumerable().Where(x => x.Code == query.Code);

        result.Items = result.Items.Concat(jobs.Select(x => new Item()
        {
            Code = x.Code,
            Id = x.Id,
            Name = x.Name,
            ContractName = x.Contract.Name,
            Type = MainPageSearchEnum.Job,
            Url = string.Format("Admin/Job/Edit/{0}", x.Id)
        })).ToList();

        //var workPhases = _db.WorkPhases.AsEnumerable().Where(x => x.ContractPhase.Code.ToLower() == query.Code.ToLower());
        var workPhases = _db.WorkPhases.AsEnumerable().Where(x => x.ContractPhase.Code == query.Code);

        result.Items = result.Items.Concat(workPhases.Select(x => new Item()
        {
            Code = x.ContractPhase.Code,
            Id = x.Id,
            Name = x.ContractPhase.Name,
            Type = MainPageSearchEnum.WorkPhase,
            Url = string.Format("Admin/WorkPhase/Edit/{0}", x.Id)
        })).ToList();

        var wbss = _db.WBSs.AsEnumerable().Where(x => x.Code == query.Code);

        result.Items = result.Items.Concat(wbss.Select(x => new Item()
        {
            Code = x.Code,
            Id = x.Id,
            Name = x.Name,
            Type = MainPageSearchEnum.WBS,
            Url = string.Format("Admin/WBS/Edit/{0}", x.Id)
        })).ToList();

        var eas = _db.EngineeringActivities.AsEnumerable().Where(x => x.Code == query.Code);

        result.Items = result.Items.Concat(eas.Select(x => new Item()
        {
            Code = x.Code,
            Id = x.Id,
            Name = x.Name,
            Type = MainPageSearchEnum.EA,
            Url = string.Format("Admin/EngineeringActivity/Edit/{0}", x.Id)
        })).ToList();

        var jcs = _db.Jobcards.AsEnumerable().Where(x => x.Code == query.Code);

        result.Items = result.Items.Concat(jcs.Select(x => new Item()
        {
            Code = x.Code,
            Id = x.Id,
            Name = x.Name,
            Type = MainPageSearchEnum.EA,
            Url = string.Format("Admin/JobCard/Edit/{0}", x.Id)
        })).ToList();

        var estimates = _db.Estimates.AsEnumerable().Where(x => x.Code == query.Code);

        result.Items = result.Items.Concat(estimates.Select(x => new Item()
        {
            Code = x.Code,
            Id = x.Id,
            Name = x.Name,
            Type = MainPageSearchEnum.Estimate,
            Url = string.Format("Estimation/Estimate/Edit/{0}", x.Id)
        })).ToList();

    }

    return result;
}

免責聲明 :我是項目Entity Framework Plus的所有者

該庫具有Query Future功能,允許在單個往返中批處理多個查詢。

例:

// using Z.EntityFramework.Plus; // Don't forget to include this.
var ctx = new EntitiesContext();

// CREATE a pending list of future queries
var futureCountries = ctx.Countries.Where(x => x.IsActive).Future();
var futureStates = ctx.States.Where(x => x.IsActive).Future();

// TRIGGER all pending queries in one database round trip
// SELECT * FROM Country WHERE IsActive = true;
// SELECT * FROM State WHERE IsActive = true
var countries = futureCountries.ToList();

// futureStates is already resolved and contains the result
var states = futureStates.ToList();

維基: EF +查詢未來

您是否嘗試過Union / UnionAll運營商?

它的目的與您希望的完全一樣 - 結合來自不同來源的相同數據。

此外,由於延遲執行的概念,您的查詢將僅在您實際迭代結果時執行(或調用執行該操作的方法,例如 - .ToList()

var contractsQuery = _db.Contracts.AsEnumerable().Where(x => x.Code == query.Code).Select(x=>new {Code=x.Code, Id=x.Id, ...});
var jobsQuery = _db.Jobs.AsEnumerable().Where(x => x.Code == query.Code).Select(x=>new{Code=x.Code, Id=x.Id, ...});
var workPhasesQuery = _db.WorkPhases.AsEnumerable().Where(x => x.ContractPhase.Code == query.Code).Select(x=>new{Code=x.Code, Id=x.Id, ...});
    // and so on
var combinedQuery = contractsQuery.UnionAll(jobsQuery).UnionAll(workPhasesQuery ).UnionAll(...
var result = combinedQuery.ToList();

類似的問題是linq實體框架中的Union
可在此處找到另一個代碼示例

請注意,這與在T-SQL 聯合中操作數據的概念完全相同,並且在封面下,您將使用union運算符獲得sql查詢

是的,肯定有一種查詢多個表的方法。 您可以為查詢使用Include()方法擴展名。 例如:

var examplelist = _db.Contracts.(v => v.id == "someid" && v.name == "anotherfilter").Include("theOtherTablesName").ToList();

您可以通過這種方式包含任意數量的表。 這是推薦的方法。

您也可以使用UnionAll()方法,但您必須為此單獨定義查詢

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM