流畅的API支持多语言数据库

时间:2014-05-01 12:59:23

标签: c# entity-framework-6.1

我在多语言网站(MVC 5,EF 6.1)上工作。为了支持某些字段的多种语言,我将表格分为两部分。一个用于语言无关数据,一个用于语言相关数据。

例如我的产品表是(简化的):

Product
 - Id int
 - Price float

ProductLang
 - ProductId int
 - LanguageId int
 - Name nvarchar
 - Desc nvarchar

因此,对于上面的结构,我创建了2个实体类和一个ModelBuilder映射:

modelBuilder.Entity<ProductLang>().HasKey(t => new { t.ProductId,  t.LanguageId });

一切正常,EF用上面的字段创建了我的数据库。此时我有点困惑。 CRUD操作的最佳方法是什么?

如何查询数据?我刚刚在下面编写了这段代码,但我不知道这是否是最好的方法:

var test = context.Product.Select(t => new 
{ 
  Id         = t.Id, 
  Price      = t.Price, 
  Translated = t.ProductLang.Where(x => x.LanguageId == 1).FirstOrDefault(),

}).FirstOrDefault();

通过这种技术,我可以非常简单地获得值:

Int32  id       = test.Id;
Double price    = test.Price;
String name     = test.Translated.Name;
String descr    = test.Translated.Descr;

如何创建新记录?我的测试代码是:

Product product1 = new Product();
product1.Price = 3.99;

context.Product.Add(product1);

ProductLang translate1 = new ProductLang();

translate1.Language = language1;
translate1.Product = product1;
translate1.Name = "My First Product";

context.ProductLang.Add(translate1);

context.SaveChanges();

上面的代码工作正常,但我不确定这是否是处理多语言(拆分表)数据库结构的最佳方法。 EF或FluentAPI中是否有任何基础设施可以更简单,更好地处理这个问题?有任何模式或惯例吗?如果我有多个翻译表,我应该使用抽象基类来处理这些操作吗?我是否应该出于任何原因使用仿制药?

1 个答案:

答案 0 :(得分:0)

考虑添加一个额外的抽象层,以保护网站的其余部分免受用于表示本地化信息的物理结构的影响。

例如,您可以创建一个平面&#34;产品&#34;无论是否已本地化,都具有相同结构的实体。在查询期间,将两个表(语言无关和本地化)映射到该数据结构中:

var test = 
(
  from t in context.ProductLang
  where t.ProductId == 5 && t.Language = "en"
  select new Website.Model.Product
  {
    Id = t.Product.Id,
    Price = t.Product.Price,  // Language independent
    Name = t.Name             // Language dependent
  }
).SingleOrDefault();

如果您将代码包装在函数或界面中,您的调用代码可以轻松检索信息,而无需担心它是如何表示的:

var test = DataService.GetProduct(5, "en");

更新可以以相同的方式工作。诀窍是更新变得有点困难,因为您不必知道是否创建与语言无关的记录。这使得更新代码更复杂 - 为了完全的线程安全,您必须使用具有锁定的事务。你可能能够使用&#34; if语句&#34;如果对本地化内容的更新很少,则在您的EF逻辑中。