5

I need to return an IEnumerable of a dynamically created Dictionary.

pseudo code:

var x = from u in Users

select new dictionary<string, string>{
    Add("Name",u.Name),
    Add("LastName",u.LastName)
}

I've been trying many ways to get the pseudo code example above but no success...

I would really appreciate your help.

1
  • Can you please describe what you're doing? IEnumerable<Dictionary<string,string>> seems a bit odd, specially when you have to hardcode all elements. Commented Aug 1, 2010 at 5:28

4 Answers 4

7
var x = from u in Users
        select new Dictionary<string, string> {
            { "Name", u.Name },
            { "LastName", u.LastName }
        };
Sign up to request clarification or add additional context in comments.

2 Comments

This thing didnt work. Throw this exception Unrecognized expression node: ListInit I tried adding and removing () after Dictionary<string,string> and no success... Any ideas...
@Tony, @mquander, Try from u in Users.AsEnumerable() as Users might be IQueryable and it's trying to convert the whole LINQ statement in SQL script.
4

The "Unrecognized expression node" error you're getting is because LINQ to SQL is failing to turn the dictionary-related code into SQL. You can use AsEnumerable() to make the compiler use LINQ to Objects instead:

var x = from u in Users.AsEnumerable()
        select new Dictionary<string, string> {
            { "Name", u.Name },
            { "LastName", u.LastName }
        };

Comments

1

That is poor use of a dictionary - you're only using it as a property bag, and create as many dictionaries as users.
A better use of the language would be creating your own User class with these properties and use that:

public class User
{
    public string Name { get; set; }
    public string LastName { get; set; }
}

And the query:

var users = Users.Select(u => new User
            {
                Name = u.Name,
                LastName = u.LastName
            });

If you'll only use the collection whiting your method, another option is to create an anonymous class:

var users = Users.Select(u => new { Name = u.Name, LastName = u.LastName });

4 Comments

I totally understand it's a very poor use of it, but i can't come with a better solution for my situation. This is the whole scenario... i am creating a series of email templates. I want to replace dynamically some texts using regex ex: "Dear [[Name]]" -> Replace([[Name]],Dictionary[Name]... The thing is that i have multiple Entities that i can gather data from. pseudo code is only using the entity User but i might have cases where i use User, UserCredit, UserAddress... so i want to return only those fields i need in my email template. anonymous class would force me to use reflection...
I did something similar recently, and had a more complex solution. What if you need different entities on the same template? "Hello [[Name]], You've ordered [[ItemsCount]] items at $[[ItemsPrice]]. Please see <a href='[[TermsURL]]'>Terms of Use</a>". I had a OrderContext class with User, Order, etc, and it can replace tokens with the appropriate string. This is probably better than turning each and every entity to a dictionary.
I thought about creating a class EmailData with as many prop as needed. Thing is that i have 29 templates and all of'em use a combination of many entities. Then i had to create anyway 29 different linqs to get the data and populate the EmailData object. Then i had to do two things. either hardcode the replace Replace("Hello [[Name]]","[[Name]]",EmailData.Name) or using regex get all those values between [[ ]] and iterate thru that collection and using reflection to call the properties in EmailData EmailData.GetType().GetProperty("Name").GetValue.ToString... so, dictionary seemed easier.
This thing didnt work. Throw this exception Unrecognized expression node: ListInit I tried adding and removing () after Dictionary<string,string> and no success... Any ideas...
1

Conversion method:

public Dictionary<string, string> ToPropertyDictionary(User theUser)
{
  Dictionary<string, string> result = new Dictionary<string, string>();
  result.Add("Name", theUser.Name);
  result.Add("LastName", theUser.Name);
  return result;
}

Called by:

IEnumerable<Dictionary<string, string>> x =
  from u in Users.AsEnumerable()  //ensure local execution by using AsEnumerable
  select ToPropertyDictionary(u);

4 Comments

An alternative here is to have a common interface for all entities, and have User.Select(u => u.ToPropertyDictionary())
This thing didnt work. Throw this exception Unrecognized expression node: ListInit I tried adding and removing () after Dictionary<string,string> and no success... Any ideas...
Users... is it a local collection?
No. Users is a System.Data.Linq.Table<Users> (LINQtoSQL)... i've been reading a lil bit, it seems that linq does not care about the Collection initializer. I can go the old boring way and do a foreach after retrieving the data from the database, but come on... we are in 2010 and i don't think we have to step back five years for something that seems so simple.... i will keep you posted.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.