我正在对查询应用过滤器,我正在尝试在其中一个过滤器中设置变量值。我尝试了各种在线示例,但每种都以不同的方式失败。
问:如何在下面的示例中设置MeterObjectState
变量?
我试过了:
SELECT( x=> { x.MeterObjectState = dataitems.Workflow; return x; })
......和其他人。
数据传输对象示例:
这是属性的部分列表:
public class DeviceDataItem
{
public int DeviceId { get; set; }
public string DeviceName { get; set; }
public int? MeterId { get; set; }
public string MeterName { get; set; }
public Workflow MeterObjectState { get; set; } //<-- I am trying to set this
// Other properties omitted ...
}
METER WORKFLOW FILTER:
我想做dataitems.Workflow = statefulDevice.Workflow
public IQueryable<DeviceDataItem> MeterWorkflowFilter(IQueryable<DeviceDataItem> query)
{
Type context = typeof(Meter);
var deviceState = (from objectState in UnitOfWork.ObjectState
join workflow in UnitOfWork.Workflow
on objectState.WorkflowId equals workflow.Id
where objectState.ContextFullName == context.FullName
group objectState by objectState.ContextId into grp
select grp.OrderByDescending(desc => desc.CreateDate)
.FirstOrDefault());
// NOTE: Here is where I have access to "statefulDevice.Workflow"
// and want to do something like "dataitems.Workflow = statefulDevice.Workflow"
var filteredQuery = (from dataitems in query //<-- QUERY
join statefulDevice in deviceState
on dataitems.MeterId equals statefulDevice.ContextId
into statefulDeviceLEFTJOIN
from statefulDevice in statefulDeviceLEFTJOIN.DefaultIfEmpty()
select dataitems.Workflow = statefulDevice.Workflow);
return filteredQuery;
}
原始查询过滤器:
您不应该需要这个来回答这个问题......但是人们经常会要求更多细节
public IQueryable<DeviceDataItem> Query()
{
var query = from device in UnitOfWork.Device
join rtuDevice in UnitOfWork.RTUDevice on device.Id equals rtuDevice.DeviceId into rtuDeviceLEFTJOIN
from rtuDevice in rtuDeviceLEFTJOIN.DefaultIfEmpty()
join commTech in UnitOfWork.User on rtuDevice.CommunicationTechnicianId equals commTech.Id into commTechLEFTJOIN
from commTech in commTechLEFTJOIN.DefaultIfEmpty()
join measureTech in UnitOfWork.User on rtuDevice.MeasurementTechnicianId equals measureTech.Id into measureTechLEFTJOIN
from measureTech in measureTechLEFTJOIN.DefaultIfEmpty()
join meter in UnitOfWork.Meter on device.Id equals meter.DeviceId into meterLEFTJOIN
from meter in meterLEFTJOIN.DefaultIfEmpty()
join meterType in UnitOfWork.MeterType on meter.MeterTypeId equals meterType.Id into meterTypeLEFTJOIN
from meterType in meterTypeLEFTJOIN.DefaultIfEmpty()
join company in UnitOfWork.Company on meter.CompanyId equals company.Id into companyLEFTJOIN
from company in companyLEFTJOIN.DefaultIfEmpty()
join meterPosition in UnitOfWork.EFMMeterPosition on meter.EFMMeterPositionId equals meterPosition.Id into meterPositionLEFTJOIN
from meterPosition in meterPositionLEFTJOIN.DefaultIfEmpty()
join runStatus in UnitOfWork.RunStatus on meter.RunStatusId equals runStatus.Id into runStatusLEFTJOIN
from runStatus in runStatusLEFTJOIN.DefaultIfEmpty()
join pipeline in UnitOfWork.Pipeline on meter.PipelineId equals pipeline.Id into pipelineLEFTJOIN
from pipeline in pipelineLEFTJOIN.DefaultIfEmpty()
select new DeviceDataItem()
{
DeviceId = device.Id,
DeviceName = device.DeviceName,
MeterPositionId = meterPosition.Id,
MeterPositionCategory = meterPosition.EFMMeterPositionCategory,
MeterId = meter.Id,
MeterName = meter.MeterName,
MeterNumber = meter.MeterNumber,
MeterTypeId = meterType.Id,
MeterTypeName = meterType.MeterTypeName,
CompanyId = company.Id,
CompanyName = company.CompanyName,
PipelineId = pipeline.Id,
PipelineName = pipeline.PipelineName,
CommunicationTechnicianId = commTech.Id,
CommunicationTechnicianFirstName = commTech.FirstName,
CommunicationTechnicianLastName = commTech.LastName,
MeasurementTechnicianId = measureTech.Id,
MeasurementTechnicianFirstName = measureTech.FirstName,
MeasurementTechnicianLastName = measureTech.LastName,
RunStatusId = runStatus.Id,
RunStatusCategory = runStatus.RunStatusCategory,
};
return query;
}
用法:
您不应该需要这个来回答这个问题......但是人们经常会要求更多细节
var application = (MeasurementContractsApplication)MeasurementContracts;
var provider = (DeviceDataItemProvider)application.DeviceDataItemProvider;
var query = provider.Query();
var publishedDevices = provider.PublishedDevicesFilter(query);
var meterByWorkflow = provider.MeterWorkflowFilter(query);
var collection = meterByWorkflow.ToDataSourceResult(request).ToList();
答案 0 :(得分:0)
我讨厌发布自己的答案。如果有人提出更有说服力的解决方案,我很乐意将其标记为正确。
<强>步骤进行:强>
<强>说明强>
事实证明,您可以在Linq查询链中多次“重置一个select子句”。但是,“数据传输对象”的组合在所有查询中必须完全相同。因此,当您使用所述“过滤器”构建原始查询时,只需“重新创建”新的返回集。
为什么不首先实现这一目标?:
如果我实现它,那么我在操作内存中的对象。这样,我可以让实体框架首先通过实现计划优化查询。
...耶!
为什么我喜欢这个?:
原始查询无需担心原始查询中任何实体的“工作流或对象状态”。但是,其他情况要求我关心各种实体的当前“状态”。现在,我可以随时将过滤器应用于原始查询...而无需重写原始查询的变体。另外,请注意我不需要实现查询来实现此目的。
因此...
......我喜欢那样。
最终查询:
在这里,我只是将“MeterObjectState”添加到属性的DeciveDataItem列表中。记住,您可以“重新投射”查询MULTIPLE TIMES ...但仅当SELECT CLAUSE在查询的整个生命周期内保持不变时。
public IQueryable<DeviceDataItem> Query()
{
var query = from device in UnitOfWork.Device
join rtuDevice in UnitOfWork.RTUDevice on device.Id equals rtuDevice.DeviceId into rtuDeviceLEFTJOIN
from rtuDevice in rtuDeviceLEFTJOIN.DefaultIfEmpty()
join commTech in UnitOfWork.User on rtuDevice.CommunicationTechnicianId equals commTech.Id into commTechLEFTJOIN
from commTech in commTechLEFTJOIN.DefaultIfEmpty()
join measureTech in UnitOfWork.User on rtuDevice.MeasurementTechnicianId equals measureTech.Id into measureTechLEFTJOIN
from measureTech in measureTechLEFTJOIN.DefaultIfEmpty()
join meter in UnitOfWork.Meter on device.Id equals meter.DeviceId into meterLEFTJOIN
from meter in meterLEFTJOIN.DefaultIfEmpty()
join meterType in UnitOfWork.MeterType on meter.MeterTypeId equals meterType.Id into meterTypeLEFTJOIN
from meterType in meterTypeLEFTJOIN.DefaultIfEmpty()
join company in UnitOfWork.Company on meter.CompanyId equals company.Id into companyLEFTJOIN
from company in companyLEFTJOIN.DefaultIfEmpty()
join meterPosition in UnitOfWork.EFMMeterPosition on meter.EFMMeterPositionId equals meterPosition.Id into meterPositionLEFTJOIN
from meterPosition in meterPositionLEFTJOIN.DefaultIfEmpty()
join runStatus in UnitOfWork.RunStatus on meter.RunStatusId equals runStatus.Id into runStatusLEFTJOIN
from runStatus in runStatusLEFTJOIN.DefaultIfEmpty()
join pipeline in UnitOfWork.Pipeline on meter.PipelineId equals pipeline.Id into pipelineLEFTJOIN
from pipeline in pipelineLEFTJOIN.DefaultIfEmpty()
select new DeviceDataItem()
{
DeviceId = device.Id,
DeviceName = device.DeviceName,
MeterPositionId = meterPosition.Id,
MeterPositionCategory = meterPosition.EFMMeterPositionCategory,
MeterId = meter.Id,
MeterName = meter.MeterName,
MeterNumber = meter.MeterNumber,
MeterTypeId = meterType.Id,
MeterTypeName = meterType.MeterTypeName,
CompanyId = company.Id,
CompanyName = company.CompanyName,
PipelineId = pipeline.Id,
PipelineName = pipeline.PipelineName,
CommunicationTechnicianId = commTech.Id,
CommunicationTechnicianFirstName = commTech.FirstName,
CommunicationTechnicianLastName = commTech.LastName,
MeasurementTechnicianId = measureTech.Id,
MeasurementTechnicianFirstName = measureTech.FirstName,
MeasurementTechnicianLastName = measureTech.LastName,
RunStatusId = runStatus.Id,
RunStatusCategory = runStatus.RunStatusCategory,
MeterObjectState = null
};
return query;
}
最终过滤器:
在这里,我正在填写一个理想的财产&amp;回归“新鲜”......
public IQueryable<DeviceDataItem> MeterWorkflowFilter(IQueryable<DeviceDataItem> query)
{
Type context = typeof(Meter);
var deviceState = (from objectState in UnitOfWork.ObjectState
join workflow in UnitOfWork.Workflow on objectState.WorkflowId equals workflow.Id
where
objectState.ContextFullName == context.FullName
group objectState by objectState.ContextId into grp
select grp.OrderByDescending(desc => desc.CreateDate).FirstOrDefault());
// NOTE: Not all Devices will immediately have a Meter
var filteredQuery = (from dataitems in query //<-- QUERY
join statefulDevice in deviceState on dataitems.MeterId equals statefulDevice.ContextId into statefulDeviceLEFTJOIN
from statefulDevice in statefulDeviceLEFTJOIN.DefaultIfEmpty()
select new DeviceDataItem()
{
DeviceId = dataitems.DeviceId,
DeviceName = dataitems.DeviceName,
MeterPositionId = dataitems.MeterPositionId,
MeterPositionCategory = dataitems.MeterPositionCategory,
MeterId = dataitems.MeterId,
MeterName = dataitems.MeterName,
MeterNumber = dataitems.MeterNumber,
MeterTypeId = dataitems.MeterTypeId,
MeterTypeName = dataitems.MeterTypeName,
CompanyId = dataitems.CompanyId,
CompanyName = dataitems.CompanyName,
PipelineId = dataitems.PipelineId,
PipelineName = dataitems.PipelineName,
CommunicationTechnicianId = dataitems.CommunicationTechnicianId,
CommunicationTechnicianFirstName = dataitems.CommunicationTechnicianFirstName,
CommunicationTechnicianLastName = dataitems.CommunicationTechnicianLastName,
MeasurementTechnicianId = dataitems.MeasurementTechnicianId,
MeasurementTechnicianFirstName = dataitems.MeasurementTechnicianFirstName,
MeasurementTechnicianLastName = dataitems.MeasurementTechnicianLastName,
RunStatusId = dataitems.RunStatusId,
RunStatusCategory = dataitems.RunStatusCategory,
MeterObjectState = statefulDevice.Workflow
});
return filteredQuery;
}
答案 1 :(得分:0)
如果您获得Microsoft的Interactive Extensions(Ix) - 只需NuGet&#34; System.Interactive&#34; - 那么你可以这样做:
void Main()
{
var foos = new List<Foo>()
{
new Foo() { Bar = 1 }
};
foreach (var f in foos.Do(f => f.Bar = 42))
{
Console.WriteLine(f.Bar);
}
}
public class Foo
{
public int Bar;
}
这会输出42
。