views:

52

answers:

2

Hi,

I have a small custom object defined as:

public class TimeSeriesDefinition
{  
    public int classID;
    public DateTime startTime;
    public DateTime endTime;
}

I'm passing a List classIDs, a List startTimes, and a List endTimes into an RIA Domain Service function. As a matter of organization, I was grouping these values into a List of TimeSeriesDefinitions and then trying to use a foreach loop to create an expression that would select with AND operators between the values in a class and OR operators between each class or implement a ".Any" query as suggested by the first answer I received below. The problem is that I can't use the TimeSeriesDefinition class in a DomainService function because it is not a primitive type or one of my entity types (maybe I should just make an entity with this type?), so I need another method of achieving the desired query results. My original idea for using expressions that I never got anywhere with is here:

        Expression<Func<EventLog, bool>> bounds;
        Boolean assignedBounds = false;
        foreach (TimeSeriesDefinition ts in reporters)
        {
            if (assignedBounds.Equals(false))
            { 
                bounds = c => c.reporterID == ts.classID && c.reportDateTime >= ts.startTime && c.reportDateTime <= ts.endTime; 
                assignedBounds = true;
            }
            else
            { 
                Expression<Func<EventLog, bool>> newBounds = c => c.reporterID == ts.classID && c.reportDateTime >= ts.startTime && c.reportDateTime <= ts.endTime;
                bounds = Expression.Or(Expression.Invoke(bounds), Expression.Invoke(newBounds);
                // bounds = Expression<Func<EventLog, bool>>.Or(bounds, newBounds);
            }
        }

        return this.ObjectContext.EventLog.Where(bounds);

My goal is for the resultset to have all records of a ts.classID between ts.startDate and ts.EndDate. From what I've found online, it seems that making sure the parameters are correctly assigned is tricky as well, but right now I'm still getting a

"Cannot implicitly convert type 'System.Linq.Expressions.BinaryExpression' to 'System.Linq.Expressions.Expression>'"

error at the line

 bounds = Expression.Or(Expression.Invoke(bounds), Expression.Invoke(newBounds);

Can anybody point me in the right direction? I suppose I could possibly build this whole thing into a query string somehow, but I'd rather not go there.

Thanks in advance for your insight!

A: 

Instead of List<TimeSeriesDefinition> can you use List<Tuple<int, DateTime, DateTime>>. Your query would then be this...

return ObjectContext.EventLog.Where(c =>
           reporters.Any(r =>
               c.reporterID == r.Item1 &&
               c.reportDateTime >= r.Item2 &&
               c.reportDateTime <= r.Item3));
whatknott
Can I then loop through the List of TimeSeriesDefinitions and call .Where on the ObjectSet and expect to get all EventLogs that meet each of the TimeSeriesDefinition sets? The key is that a given classID has a specific startTime and endTime that are only valid for that classID, and I have multiple sets of {classID, startTime, endTime} to query. In my tests, stringing these together as .Where clauses put AND statements between each set of {classID, startTime, endTime}, rather than the OR that I'm going for... hence the use of Expressions.
whatknott
Oh wow... missed the "(r =>" on the first read through... that makes sense! I'm having trouble with the VPN I need to test the solution right now but when that's back and running I'll give this a test and report back/mark answered (pretty sure this is going to work). THANKS AGAIN!
OK... I thought this was working and it might have worked, except that this is a domain service function and I'm not allowed to use non-primitive classes in it. In other words, I can pass in the ordered lists of classID, startTime, and endTime (which will all have the same length), but I cannot then serialize those 3 values into a list of objects that can then be used as part of an ".Any" query pattern as whatknott showed me above. Does anyone have any ideas for how I can get around this limitation and still execute the linq query I'm trying to execute?