0

So I have this multilingual datamodel: Product -> ProductTranslation

  • Product has an Id property.
  • ProductTranslation has a Culture (e.g. 'nl') and a Name property.

I already have a working query that flattens a product for a specific language to a ProductModel (using Automapper).

  • ProductModel has an Id and a Name property.

ProductModel.Name contains the Name from the appropriate ProductTranslation, which I determine in the query by comparing the client application culture to ProductTranslation.Culture.

So far all good and no LINQKit involved.

Now I'd like to sort the products returned by ProductTranslation.Name. My question is if this can be using LINQKit. I do want to do the sorting on the database side, so materializing and doing it on the client side is no option (left out paging to simplify the example here).

I do have an expression already that will determine the correct translation:

Expression<Func<ICollection<ProductTranslation>, ProductTranslation>> expression =
            translations => translations.FirstOrDefault(t => t.Culture.Equals(cultureName))
                 ?? translations.FirstOrDefault();

Can I somehow expand on this to get the Name property from the ProductTranslation this returns and apply it as a sorting expression?

Thanks in advance, cheers!

Raymond Brink
  • 191
  • 1
  • 1
  • 8

1 Answers1

0

After some more investigating this seems to work fine:

var cultureName = Thread.CurrentThread.CurrentCulture.Name;
var languageName = Thread.CurrentThread.CurrentCulture.TwoLetterISOLanguageName;

return s => s.FirstOrDefault(t => t.Culture == cultureName).Name ??
            s.FirstOrDefault(t => t.Culture == languageName).Name ??
            s.FirstOrDefault().Name;

Unfortunately this only resolves part of my problem. The issue left is, that I'd like to be able to specify the property (in this case Name) using another lambda expression of type Expression<Func<ProductTranslation>, object>, which I can pass to the method that creates the expression.

So in that method I end up with two expression that I need to combine. It boils down to this:

public static Expression<Func<Product, object>> FromTranslation
{
    get
    {
        var cultureName = Thread.CurrentThread.CurrentCulture.Name;
        var languageName = Thread.CurrentThread.CurrentCulture.TwoLetterISOLanguageName;

        Expression<Func<Product, ProductTranslation>> translationExpression = s =>
            s.Translations.FirstOrDefault(t => t.Culture == cultureName) ??
            s.Translations.FirstOrDefault(t => t.Culture == languageName) ??
            s.Translations.FirstOrDefault();

        Expression<Func<ProductTranslation, object>> memberExpression = t => t.Name;

        // TODO: Combine expressions somehow?
        return ??;
    }
}

Can I somehow extend the translationExpression with the memberExpression, so I end up with one expression?

Raymond Brink
  • 191
  • 1
  • 1
  • 8