如何解决将 OUTER APPLY 用于 SqlQuery<T>,其中 T 具有 IEnumerable 属性
由于使用 Linq 的性能问题,我正在使用字符串 sql 查询。由于很多outer apply,而且很多where子句使用IN。为清楚起见,此示例中的代码在此处进行了缩减。我省略了向 where 子句添加(或不添加)大量代码的 IF-ELSE 语句。
这是我的业务对象,它有一个 IEnumerable 作为属性。
public class AssetBO
{
public Guid AssetId { get; set; }
public Guid SiteId { get; set; }
public string Name { get; set; }
public IEnumerable<AssetDivisionBO> AssetDivisionInfo { get; set; }
}
这是我的字符串 sql:
string sql_Data = @"SELECT disTINCT e.AssetId,e.SiteId,e.Name
FROM
Asset.vAssetLinkBox e
OUTER APPLY (
SELECT
ld.AssetDivisionId,ld.SiteId,ld.AssetId,ld.DivisionId,ld.IsDeleted,ld.Created,ld.LastModified,ld.ModifiedByEmployeeId,ld.CreatedByEmployeeId,FROM Asset.AssetDivision ld
WHERE
ld.IsDeleted = 0
AND ld.AssetId = e.AssetId
) AS AssetDivisionInfo
WHERE
e.IsDeleted = 0";
然后我运行这个:
var query = context.Database.sqlQuery<AssetBO>(sql_Data);
List<AssetBO> assets = query.ToList<AssetBO>();
我想从字符串 sql 中的 OUTER APPLY 填充 IEnumerable AssetDivisionInfo。这可能吗?
我得到了我的 AssetBO 对象,而 AssetDivisionInfo 为空。有没有办法映射它?
编辑:我被要求提供原始的 Linq,所以现在将其发布在这里。我需要所有这些 OUTER APPLIES 与数据一起返回。
public static List<ModuleView.AssetBO> Asset_GetList_ByRadFilter(COG_ContextDB context,RadFilter filter,string where_clause,Guid Base_ContextSiteId,Guid Base_ContextEmployeeId,HashSet<Guid> PassedAssetIdList,bool Base_ContextEmployee_IsForAllDivisions,int PageNumber,int PageSize,string OrderByField,bool IsDescending,bool IsRestrictedByDivision,HashSet<Guid?> Employee_DivisionIdList,out int RecordCount)
{
var interceptor = new Common.BLL.CommandInterceptorHelper();
System.Data.Entity.Infrastructure.Interception.DbInterception.Add(interceptor);
HashSet<Guid> IsForAll_AssetIdList = new HashSet<Guid>();
if (IsRestrictedByDivision == true)
{
//db hit,so calling only if IsRestrictedByDivision == true
IsForAll_AssetIdList = GetIsForAllDivisions_Assets(context,Base_ContextSiteId);
}
else
{
Base_ContextEmployee_IsForAllDivisions = false;
}
var query = from e in context.vAssetLinkBoxes
from cbu in context.Employees.Where(emp => emp.EmployeeId == e.CreatedByEmployeeId && emp.IsDeleted == false).DefaultIfEmpty()
//OUTER APPLY to get a list of AssetIds from AssetDivision table,that are in the employees DivisionIdList (divisions he has access to.) DEV-3504
let AssetIdList = (from dv in context.AssetDivisions.Where(div => div.AssetId == e.AssetId && div.IsDeleted == false && Employee_DivisionIdList.Contains(div.DivisionId)) select dv.AssetId).ToList<Guid>()
join assetUsageInfo in
(
from e in context.AssetUsages
from cbu in context.Employees.Where(emp => emp.EmployeeId == e.CreatedByEmployeeId && emp.IsDeleted == false).DefaultIfEmpty()
where e.IsDeleted == false
select new ModuleView.AssetUsageBO
{
AssetUsageId = e.AssetUsageId,SiteId = e.SiteId,AssetId = e.AssetId,AssetUsageTypeId = e.AssetUsageTypeId,ImportId = e.ImportId,IsDeleted = e.IsDeleted,Created = e.Created,LastModified = e.LastModified,ModifiedByEmployeeId = e.ModifiedByEmployeeId,CreatedByEmployeeId = e.CreatedByEmployeeId,CreatedByEmployeeName = (!string.IsNullOrEmpty(cbu.FirstName)) ? cbu.LastName + "," + cbu.FirstName : cbu.LastName,IsDirty = false,IsNew = false,}
) on e.AssetId equals assetUsageInfo.AssetId into assetUsageInfos
join assetExtendedFieldInfo in
(
from e in context.AssetExtendedFields
from cbu in context.Employees.Where(emp => emp.EmployeeId == e.CreatedByEmployeeId && emp.IsDeleted == false).DefaultIfEmpty()
where e.IsDeleted == false
orderby e.FieldName
select new ModuleView.AssetExtendedFieldBO
{
AssetExtendedFieldId = e.AssetExtendedFieldId,FieldName = e.FieldName,FieldLabel = e.FieldLabel,FieldValue = e.FieldValue,FieldDataType = e.FieldDataType,}
) on e.AssetId equals assetExtendedFieldInfo.AssetId into assetExtendedFieldInfos
join assetDivisionInfo in
(
from e in context.AssetDivisions
from d in context.Divisions.Where(emp => emp.DivisionId == e.DivisionId && emp.IsDeleted == false)
from a in context.Assets.Where(emp => emp.AssetId == e.AssetId && emp.IsDeleted == false)
from cbu in context.Employees.Where(emp => emp.EmployeeId == e.CreatedByEmployeeId && emp.IsDeleted == false).DefaultIfEmpty()
where e.IsDeleted == false
select new ModuleView.AssetDivisionBO
{
AssetDivisionId = e.AssetDivisionId,DivisionId = e.DivisionId,DivisionName = d.DivisionName,AssetName = a.Name,}
) on e.AssetId equals assetDivisionInfo.AssetId into assetDivisionInfos
where e.SiteId == Base_ContextSiteId
&& (IsRestrictedByDivision == false || (IsRestrictedByDivision == true && (Base_ContextEmployee_IsForAllDivisions == true || AssetIdList.Contains(e.AssetId) || IsForAll_AssetIdList.Contains(e.AssetId)))) //from outer apply
select new ModuleView.AssetBO
{
AssetId = e.AssetId,AssetTypeId = e.AssetTypeId,Name = e.Name,Description = e.Description,UniqueIdentity = e.UniqueIdentity,StatusId = e.StatusId,CompanyId = e.CompanyId,Make = e.Make,Model = e.Model,Year = e.Year,SerialNumber = e.SerialNumber,PhoneNumber = e.PhoneNumber,Email = e.Email,IsActive = e.IsActive,BlockedTimeIsEnabled = e.BlockedTimeIsEnabled,IsForAllDivisions = e.IsForAllDivisions,AssetTypeName = e.AssetTypeName,StatusName = e.StatusName,CompanyName = e.CompanyName,ModifiedByEmployeeName = e.ModifiedByEmployeeName,NumCaptainsOnBoard = (e.CaptainNum == null) ? 0 : (int)e.CaptainNum,ActivityTimeInMin = e.TotalDurationInMin,AssetUsageInfo = assetUsageInfos,AssetExtendedFieldInfo = assetExtendedFieldInfos,AssetDivisionInfo = assetDivisionInfos,DivisionDelimitedString = "",//must be here to avoid error when sorting. Sort is done in BA code.
};
if (string.IsNullOrEmpty(where_clause))
{
where_clause = DataFilterBA.GetFilterWhereClause(context,filter,"ASSET",Base_ContextEmployeeId,Base_ContextSiteId,"LINQ");
}
int SkipRows = (PageNumber - 1) * PageSize;
if (PassedAssetIdList.Count == 0)
{
RecordCount = query.Where(where_clause).Select(d => d.AssetId).distinct().Count();
//RecordCount = query.Where(where_clause).GroupBy(test => test.AssetId)
// .Select(grp => grp.FirstOrDefault()).Count();
query = query.Where(where_clause).OrderBy(OrderByField + (IsDescending ? " descending" : ""));
}
else
{
RecordCount = query.Where(x => PassedAssetIdList.Contains(x.AssetId)).Where(where_clause).Select(d => d.AssetId).distinct().Count();
query = query.Where(x => PassedAssetIdList.Contains(x.AssetId)).Where(where_clause).OrderBy(OrderByField + (IsDescending ? " descending" : ""));
}
List<ModuleView.AssetBO> items = new List<ModuleView.AssetBO>();
if (PageSize == -1)
{
items = query.ToList<ModuleView.AssetBO>();
}
else
{
items = query.Skip(SkipRows).Take(PageSize).ToList<ModuleView.AssetBO>();
}
System.Data.Entity.Infrastructure.Interception.DbInterception.Remove(interceptor);
if (items != null && items.Count > 0)
{
items = items.GroupBy(test => test.AssetId)
.Select(grp => grp.FirstOrDefault())
.ToList();
return items;
}
return new List<ModuleView.AssetBO>();
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。