Paul Clark
Paul Clark

Reputation: 43

C# How do I use a variable in a Linq select statement using Query Syntax

I'm trying to get the name of item but I'm having to hard code the locale in the select statement. This is my code

private void GetOrder(Root Wix)
    {
        string locale = Wix.restaurant.locale;
        List<Item> menu = Wix.menu.items;
        List<OrderItem> orderItems = Wix.order.orderItems;
        foreach (var orderItem in orderItems)
        {
            string itemId = orderItem.itemId;
            string itemName = (from m in menu  where m.id==itemId select m.title.en_GB).FirstOrDefault();

            int count = orderItem.count;
            string comment = orderItem.comment;
            int price = orderItem.price;
        }

        string orderComment = Wix.order.comment;
        int totalPrice = Wix.order.price;
    }

How can I replace the hard coded "en_GB" in select m.title.en_GB to the locale value returned in the string locale = Wix.restaurant.locale ?

Upvotes: 0

Views: 909

Answers (2)

SomeBody
SomeBody

Reputation: 8743

You can use reflection:

string itemName = (from m in menu  where m.id==itemId select (string)m.title.GetType().GetProperty(locale).GetValue(m.title)).FirstOrDefault();

This will throw an exception if the class of your title object has no property that has the same name as the content of the string locale. The following variant will make your itemName null if no such property exists:

string itemName = (from m in menu  where m.id==itemId select (string)m.title.GetType().GetProperty(locale)?.GetValue(m.title)).FirstOrDefault();

Upvotes: 3

Alexey Rumyantsev
Alexey Rumyantsev

Reputation: 523

Instead of using slow reflection based approach you can introduce interface like this

public interface ILocalizableString
{
    string en_GB { get; }

    string ru_RU { get; }

    //and so on
}

Implement it by your localized strings and introduce extension method

public static class LocalizableStringExtensions
{
    public static string GetString(this ILocalizableString str, string locale)
    {
        if(str == null)
            return null;
        if(locale == "en_GB")
            return str.en_GB;
        if(locale == "ru_RU")
            return str.ru_RU;
        return str.en_GB; //default
     }
  }

Then in your code

  string itemName = (from m in menu  where m.id==itemId select m.title.GetString(locale)).FirstOrDefault();

This can guarantee good performance, and simple way to extended list of supported languages.

Upvotes: 3

Related Questions