dtretyakov/WindowsAzure

Observations: Possible Issues

Opened this issue · 1 comments

A week ago I started writing something semilar as this project and first found this project today.

I have borrowed the QueryProvider implementation (and also attached your license file).

I have a few observations that could possible create some issues for your later and just wanted to share. If its of no use for you, just ignore this.

To get my stuff working I found that I had to reverse the order of your lambda compilation:

        private static Delegate MergeLambdasAndCompile(IList<LambdaExpression> expressions)
        {
            if (expressions.Count == 0)
            {
                return null;
            }
            int i = expressions.Count-1;
            LambdaExpression lambda = expressions[i--];

            for (; i >= 0; i--)
            {
                InvocationExpression invoked = Expression.Invoke(expressions[i], lambda.Body);
                lambda = Expression.Lambda(invoked, lambda.Parameters);
            }

            return lambda.Compile();
        }

to make the following test work: If not, the nit tries to apply the last select first and then at the end it do the projection from entity type to string, but there is no entity type at that point.

        [TestMethod]
        public void SelectServerSideProjection()
        {

            var context = new NewTableStorageContext();

            //This call should project name to PartitionKey
            var query = from ent in context.People
                        select new { ent.Name, ent.Age };

            //The following query get build such only the Name column is
            //retrieved from the server, and its mapped such it know to do
            //the filter on partition key and not the name. (Model Builder)
            var result = query.Select(t => t).Where(t=>true).Select(t=>t.Name).ToArray();
        }

I also added the following to the selectTranslator, to support a few cases like those in comments.:

            }else if(lambda.Body.NodeType == ExpressionType.Parameter)
            {
                // from ent in source select ent.
            }else if(lambda.Body.NodeType == ExpressionType.MemberAccess)
            {
                //from ent in source select ent.Name
                var memberAccess = (MemberExpression)lambda.Body;
                AddColumn(memberAccess.Member.Name, result);
            }

I didnt do a pull request because I dont have the full overview over your project and just wanted to let you know what changes I made for my library. Hope its usefull for you, if not just ignore

Poul,

Thanks for sharing your experience, I'll keep it to check out my LINQ provider implementation.