Wrox Programmer Forums

Need to download code?

View our list of code downloads.

Go Back   Wrox Programmer Forums > ASP.NET and ASP > Other ASP.NET > BOOK: Professional ASP.NET Design Patterns
Password Reminder
Register
| FAQ | Members List | Search | Today's Posts | Mark Forums Read
BOOK: Professional ASP.NET Design Patterns
This is the forum to discuss the Wrox book Professional ASP.NET Design Patterns by Scott Millett; ISBN: 978-0-470-29278-5
Welcome to the p2p.wrox.com Forums.

You are currently viewing the BOOK: Professional ASP.NET Design Patterns section of the Wrox Programmer to Programmer discussions. This is a community of tens of thousands of software programmers and website developers including Wrox book authors and readers. As a guest, you can read any forum posting. By joining today you can post your own programming questions, respond to other developers’ questions, and eliminate the ads that are displayed to guests. Registration is fast, simple and absolutely free .
DRM-free e-books 300x50
Reply
 
Thread Tools Search this Thread Display Modes
  #1 (permalink)  
Old January 24th, 2012, 05:35 PM
Registered User
Points: 13, Level: 1
Points: 13, Level: 1 Points: 13, Level: 1 Points: 13, Level: 1
Activity: 0%
Activity: 0% Activity: 0% Activity: 0%
 
Join Date: Jan 2012
Location: Switzerland
Posts: 3
Thanks: 0
Thanked 0 Times in 0 Posts
Default Entity Framework Query Translator

The book is really great, especially chapter 7 helped me organize my applications a lot. But since I'm using Entity Framework as my OM I'm struggling with the QueryTranslator class introduced in chapter 7. What I'd really like to see is a QueryTranslator class for Entity Framework for the case study. The class in chapter 7 works only with one criteria and subqueries are not handled either. I came up with something like a list of strings and then folding the operator into it. But I'm not really confident enough in C# to say that is a good solution. Also, if I want to have two predicates for the same property, I get some troubles with the ObjectParameter name. Let's say I want to find all product from category a and from subcategory b, so I will get a query similar to p.CategoryId = @CategoryId or p.CategoryId = @CategoryId. In this case I obviously get the error that the name for the ObjectParameter is not unique. Can anyone help or give me a hint?!
Reply With Quote
  #2 (permalink)  
Old January 25th, 2012, 05:03 AM
Registered User
Points: 13, Level: 1
Points: 13, Level: 1 Points: 13, Level: 1 Points: 13, Level: 1
Activity: 0%
Activity: 0% Activity: 0% Activity: 0%
 
Join Date: Jan 2012
Location: Switzerland
Posts: 3
Thanks: 0
Thanked 0 Times in 0 Posts
Default Code Example

Here is my code:

Code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.Objects;

using Infrastructure.Querying;

namespace Repositories.EF.QueryTranslators
{
    public class QueryTranslator
    {
        private int ParameterCounter = 1;

        public string CurrentParameterNr { get { return "p" + ParameterCounter++.ToString(); } }

        public void CreateQueryAndObjectParameters(Query query, StringBuilder queryBuilder, IList<ObjectParameter> paraColl)
        {
            IList<string> criteriaStringList = new List<string>();

            if (query.Criteria != null)
            {
                foreach (Criterion criterion in query.Criteria)
                {
                    string currentParameterNr = CurrentParameterNr;
                    switch (criterion.criteriaOperator)
                    {
                        case CriteriaOperator.Equal:
                            criteriaStringList.Add(String.Format("it.{0} = @{1}", criterion.PropertyName, currentParameterNr));
                            break;

                        case CriteriaOperator.LessThanOrEqual:
                            criteriaStringList.Add(String.Format("it.{0} <= @{1}", criterion.PropertyName, currentParameterNr));
                            break;

                        case CriteriaOperator.LessThan:
                            criteriaStringList.Add(String.Format("it.{0} < @{1}", criterion.PropertyName, currentParameterNr));
                            break;

                        case CriteriaOperator.HigherThanOrEqual:
                            criteriaStringList.Add(String.Format("it.{0} >= @{1}", criterion.PropertyName, currentParameterNr));
                            break;

                        case CriteriaOperator.HigherThan:
                            criteriaStringList.Add(String.Format("it.{0} > @{1}", criterion.PropertyName, currentParameterNr));
                            break;

                        default:
                            throw new ApplicationException("No operator defined");
                    }

                    paraColl.Add(new ObjectParameter(currentParameterNr, criterion.Value));
                }

                string queryOperator;
                if (query.QueryOperator == QueryOperator.And) queryOperator = " and ";
                else queryOperator = " or ";

                queryBuilder.Append(String.Join(queryOperator, criteriaStringList));

                foreach (Query subQuery in query.SubQueries)
                {
                    queryBuilder.Append(queryOperator);
                    queryBuilder.Append(" (");
                    CreateQueryAndObjectParameters(subQuery, queryBuilder, paraColl);
                    queryBuilder.Append(") ");
                }
            }
        }
    }
}
Obviously not the best solution, but it works. Since I'm not satisfied with a solution that just works I would be glad if anyone could help me find a more elegant way ;-)
Reply With Quote
  #3 (permalink)  
Old August 14th, 2012, 07:45 AM
Registered User
Points: 11, Level: 1
Points: 11, Level: 1 Points: 11, Level: 1 Points: 11, Level: 1
Activity: 0%
Activity: 0% Activity: 0% Activity: 0%
 
Join Date: Jun 2012
Posts: 3
Thanks: 0
Thanked 0 Times in 0 Posts
Default How did you get on?

I've also hit this problem, from briefly looking at your code it seems a reasonable extension of the solution Scott offers.

However I recon it must be possible to write a query object that revolves around Lambda expressions, which can then be used directly by Linq-to-Entities and save all that pain.

I'm thinking along the lines of Query<T> so you'd create var query = new Query<Product>() for example, then you'd add a criteria to to along the lines of query.Add(new Criteria(m => m.ProductType == "Books")). Then in the query translator you'd extract these criteria and add them as .Where(Critera[0]).Where(Criteria[1]).

I don't know how practical it is yet as I am fairly new to all the Lambda stuff, but it will be my preferred way forward if I can get it to work.
Reply With Quote
Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off
Trackbacks are Off
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Having problems with Entity Framework Rushino ASP.NET 4 General Discussion 7 June 12th, 2013 05:17 PM
Entity Framework Question nanonerd BOOK: Beginning ASP.NET 4 : in C# and VB 3 January 15th, 2012 07:59 AM
Entity Framework Code First 4.1 JackHerr BOOK: Professional ASP.NET MVC 3 3 September 16th, 2011 05:15 PM
Switching To entity framework luckystar BOOK: ASP.NET 3.5 Enterprise Application Development with Visual Studio 2008: Problem Design Solutio 0 July 31st, 2009 09:52 PM



All times are GMT -4. The time now is 07:25 AM.


Powered by vBulletin®
Copyright ©2000 - 2020, Jelsoft Enterprises Ltd.
© 2013 John Wiley & Sons, Inc.