I'm trying to dynamically compose a groupby query with queryspec, and I am able to do just about everything I need to except I'm getting hung up on the Select projection. If I do this it works fine:
var qf = new QueryFactory();
List<object> groupFields = new List<object>();
var workerQuery = qf.Worker
.InnerJoin(qf.Task).On(WorkerFields.Id == TaskFields.WorkerId)
.InnerJoin(qf.TaskDefinition).On(TaskDefinitionFields.Id == TaskFields.DefinitionId);
groupFields.Add(WorkerFields.Group1Id);
workerQuery = workerQuery.InnerJoin(qf.WorkerGroup).On(WorkerFields.Group1Id == WorkerGroupFields.Id);
groupFields.Add(TaskFields.DefinitionId);
groupFields.Add( TaskDefinitionFields.Title );
groupFields.Add( WorkerGroupFields.Description );
var query = qf.Create().Select(() =>
new {
GroupDescr = WorkerGroupFields.Description.ToValue<string>(),
TaskDefName = TaskDefinitionFields.Title.ToValue<string>() ,
TotalCount = WorkerFields.Id.Count().As("Counted").ToValue<int>()
})
.From(workerQuery)
.Where( TaskFields.CompletedUTC != DBNull.Value)
.Where( WorkerFields.Group1Id != DBNull.Value)
.GroupBy( groupFields.ToArray());
this.AdapterToUse.FetchQuery(query).Dump();
I took out all of the conditional code to simplify the example, but the idea is that I am able to build up the groupFields collection and inner joins dynamically, but so far I haven't been able to do the same for the .Select. I want to replace the anonymous type with something like an ExpandoObject so I can conditionally choose which fields to include(this would coincide with conditional decisions of what groupbys to include).
dynamic projection = new System.Dynamic.ExpandoObject();
IDictionary<string, object> dictionary = (IDictionary<string, object>)projection;
dictionary.Add("GroupDescr", WorkerGroupFields.Description.ToValue<string>());
dictionary.Add("TaskDefName", TaskDefinitionFields.Title.ToValue<string>());
dictionary.Add("TotalCount", WorkerFields.Id.Count().As("Counted").ToValue<int>());
var query = qf.Create().Select(() => projection)
.From(workerQuery)
//...
Error: "No projection elements specified."
So I took a step back and just tried declaring the anonymous type outside of the expression(even though this doesn't give me the dynamic capability I need, it is just troubleshooting step):
var projection = new {
GroupDescr = WorkerGroupFields.Description.ToValue<string>(),
TaskDefName = TaskDefinitionFields.Title.ToValue<string>() ,
TotalCount = WorkerFields.Id.Count().As("Counted").ToValue<int>()
};
var query = qf.Create().Select(() => projection )
.From(workerQuery)
//...
Error: "No projection elements specified."
I'm not really sure why this last one would not work, as it seems identical to declaring the anonymous type inline. The .Select() would infer the anonymous type from the projection variable. I suspect the problem is some nuance of expressions that I don't understand.
I've tried the other overload of .Select that takes a params [] object, similar to how I used groupFields list, but I don't know how to include aggregate functions in that.
Anyone have any suggestions?
LLBLGen DLL File version is 3.5.12.317