为什么Linq to Entities无法将此调用转换为SQL?

时间:2018-07-16 13:01:12

标签: c# entity-framework linq

var providerTypes = from provider_types in dbContext.vw_LookUpProviderType
                         select new vw_LookUpProviderType
                         {
                             ApplicationUser = provider_types.ApplicationUser,
                             ProviderTypeId = provider_types.ProviderTypeId,
                             Type = provider_types.Type
                         };


            var query =
                from providerCoi in dbContext.Provider_COI
                where providerCoi.COIProviderId == message.ProviderId
                join providerDetail in dbContext.ProviderDetail
                on providerCoi.ProviderId equals providerDetail.ProviderId
                into providerDetails
                from providerDetail in providerDetails.DefaultIfEmpty()
select new Result
                {
                    PhysicianAdvisorId = providerCoi.ProviderId,
                    HasConflictOfInterest = providerCoi.COIFlag == true,
                    PhysicianAdvisorName = providerDetail.FirstName + " " + providerDetail.MiddleName + " " + providerDetail.LastName,
                    ProviderType = providerTypes
                        .Where(providerType => providerDetail.ProviderTypeIds.Contains(providerType.ProviderTypeId.ToString()))
                        .Select(providerType => providerType.Type)
                        .ToArray<string>()
                        .Aggregate((current, next) => current +", " + current)
                };

我选择了providerTypes。有表providerDetails,并且有字段providerTypeIds-不能更改。例如providerTypes: [1: 'Type 1', 2: 'Type 2', 3: 'Type 4']providerTypeIds: '1,2,'

  1. 从providerTypes中选择可以在providerIdsString中找到的类型 providerTypes.Where(providerType => providerDetail.ProviderTypeIds.Contains(providerType.ToString())) // => [1: 'Type 1', 2: 'Type 2']
  2. 比在字符串表示形式上进行选择:.Select(providerType => providerType.Type) // => ['Type 1', 'Type 2']
  3. 最后将它们全部转换为用逗号分隔的类型的字符串: .ToArray<string>() .Aggregate((current, next) => current +", " + current) // => 'Type 1, Type 2

这会引发异常

  

LINQ to Entities无法识别方法'System.String   Aggregate [String](System.Collections.Generic.IEnumerable 1[System.String], System.Func 3 [System.String,System.String,System.String])'

1 个答案:

答案 0 :(得分:0)

因此,如评论中所述,Linq to Entities不支持Aggregate函数,有关更多详细信息,请参见参考:https://docs.microsoft.com/en-us/dotnet/framework/data/adonet/ef/language-reference/supported-and-unsupported-linq-methods-linq-to-entities#aggregate-methods

不幸的是toList并没有帮助我,我不知道特定的原因,但是也许是因为使用了搜索字段-providerTypes,也许providerTypes上的toList可能会有所帮助,但我使用了另一种解决方法-选择doctorIds字符串,然后手动对其进行转换。参见下面的代码。

//select provider types lookup, from there can map id with it text meaning, f.e.[{providerTypeId: 1, type: 'Value 1' },{providerTypeId: 2, type: 'Value 2' }]
var providerTypes = exUrDataContext.vw_LookUpProviderType.ToList();

//select physicianCois with unmodified providerTypeIds(f.e '1,2,')
var physicianCois =
                await (from providerCoi in dbContext.Provider_COI
                       where providerCoi.COIProviderId == message.PhysicianId
                       join providerDetail in exUrDataContext.vw_ProviderDetail
                       on providerCoi.ProviderId equals providerDetail.ProviderId
                       into providerDetails
                       from providerDetail in providerDetails.DefaultIfEmpty()
                       select new Result
                       {
                           PhysicianAdvisorId = providerCoi.ProviderId,
                           HasConflictOfInterest = providerCoi.COIFlag == true,
                           PhysicianAdvisorName = providerDetail.FirstName + " " + providerDetail.MiddleName + " " + providerDetail.LastName,
                           ProviderType = providerDetail.ProviderTypeIds
                       }).ToListAsync();

            //map string with ids to string from text values, f.e. '1,2' => 'Value 1, Value 2'
            foreach (var physicianCoi in physicianCois)
            {
                string physicianProviderNames = "";
                foreach (var providerKey in physicianCoi.ProviderType.Split(new char[] { ',' }, System.StringSplitOptions.RemoveEmptyEntries))
                {
                    if (!physicianProviderNames.Equals(""))
                    {
                        physicianProviderNames += ", ";
                    }
                    physicianProviderNames += providerTypes.Where(providerType => providerType.ProviderTypeId == int.Parse(providerKey)).FirstOrDefault().Type;
                }
                physicianCoi.ProviderType = physicianProviderNames;
            }