0

I am using Entity Framework Code-First approach. Below is my sample Model.

    public class LocalizableEntity
    {
    public int Id{get;set;}

    // this property is 'Ignore'd. Need to set this.
    public string Name{get;set;}

    // this is the collection of 'Name's in all supported cultures.
    public virtual ICollection<LocalizationText> LocalNames{get;set;}
    }

Using fluent API, the 'Name' property will be ignored, like Ignore(t=>t.Name). My idea is to set the Name property from LocalNames collection by querying with a given culture ID. The LocalizationText type will look like below.

public class LocalizationText
{
public int Id{get;set;}
public string Text{get;set;}
public string Culture{get;set;}
}

I want to implement methods to SELECT the items in SINGLE, ALL and BY PREDICATE in my repository(please consider LocalizableEntities and LocalizationText are the DbSets), but with populating the Name property in one query.

GET SINGLE ITEM method

public LocalizableEntity GetById(int id)
{
var result=LocalizableEntities.Find(id); // selects the item

//the culture will be passed in by other way. Hard-coding here
result.Name=LocalizableEntities.LocalNames.Single(t=>t.Culture=="en-us");
return result;
}

But the above implementation will take two DB calls. I want to make this into one query/expression. I also need to do this when selecting in batch also, assigning value for Name over sequence.

Is this possible with single query? If yes, can anyone please guide me? Thanks :)

Ananthan Unni
  • 1,304
  • 9
  • 23

1 Answers1

0

Ignoring the entity model field kind of smells. Your design seems well suited to a ViewModel. So then assuming you have an entity model called LocalizationText and a ViewModel called LocalizableEntityVM you could do something like:

public LocalizableEntityVM GetById(int id, string culture)
{
    var result=LocalizationText.Single(le => le.id && le.Culture == culture)
                  .Select(le => new LocalizableEntityVM 
                   {
                         Name = le.Text
                   });

    return result;
}
Steve Greene
  • 12,029
  • 1
  • 33
  • 54
  • thanks for your reply. But wouldn't it take 2 DB calls to retrieve the entity and the associated localized text? What I did for now is I used the Select a 'new dynamic object' with real entity and the Name from localization logic, and then assigning this value in another statement in my repository method. Not sure how bad that sounds like. – Ananthan Unni May 03 '16 at 03:00
  • No, but if you prefer your method you could always do an include which does a join behind the scenes: var localizableEntityAndChildren = LocalizableEntities.Include(le => le.LocalNames)... – Steve Greene May 03 '16 at 12:48