我试图在我的实体框架模型中添加对多语言分类字符串的支持。这是我有:使用ExpressionVisitor修改表达式以实现自动翻译
实体:
public partial class ServiceState : ITranslatableEntity<ServiceStateTranslation>
{
public int Id { get; set; }
public string Name { get; set; }
public virtual ICollection<ServiceStateTranslation> Translations { get; set; }
}
ITranslatableEntity接口:
public interface ITranslatableEntity<T>
{
ICollection<T> Translations { get; set; }
}
然后将含有翻译的实体:
public partial class ServiceStateTranslation
{
public int Id { get; set; }
[Index("IX_ClassificationTranslation", 1, IsUnique = true)]
public int MainEntityId { get; set; }
public ServiceState MainEntity { get; set; }
[Index("IX_ClassificationTranslation", 2, IsUnique = true)]
public string LanguageCode { get; set; }
public string Name { get; set; }
}
包含属性的名称本地化的字符串在主实体和翻译实体中总是相同的(0在这种情况下为)。
使用这种模式,我可以做这样的事情:
var result = query.Select(x => new
{
Name = x.Name,
StateName =
currentLanguageCode == DEFAULTLANGUAGECODE
? x.ServiceState.Name
: x.ServiceState.Translations.Where(i => i.LanguageCode == currentLanguageCode)
.Select(i => i.Name)
.FirstOrDefault() ?? x.ServiceState.Name
}).ToList();
的问题是我不喜欢写这种代码包含任何意译的实体每个查询,所以我正在考虑使用QueryInterceptor
和ExpressionVisitor
这将做一些魔术和允许我用这样的替换查询:
var result = query.Select(x => new
{
Name = x.Name,
StateName = x.ServiceState.Name
}).ToLocalizedList(currentLanguageCode, DEFAULTLANGUAGECODE);
我想这是可能创造一个ExpressionVisitor这将:
- 只有改变
Select
块导航属性里面的表达式实现ITranslatableEntity<>
接口 如果当前的语言不是默认情况下,表达
x.ServiceState.Name
改变x.ServiceState.Translations.Where(i => i.LanguageCode == currentLanguageCode) .Select(i => i.Name) .FirstOrDefault() ?? x.ServiceState.Name
但我不是那种熟悉表情的游客和树木,所以我在这里有点迷路。有人能让我走上正轨吗?
https://msdn.microsoft.com/en-us/library/bb882521%28v=vs.90%29.aspx – 2015-04-02 12:02:56
我m使用.NET 4.5,所以ExpressionVisitor已经在那里实现了,我需要覆盖它以满足我的需求。无论如何,我已经想出了一个解决方案,稍后会发布一个答案。 – Donatas 2015-04-03 07:14:32