首先使用EF代码本地化实体的最佳实践

时间:2014-08-14 07:30:46

标签: entity-framework localization entity-framework-4

我正在使用EF Code First开发一个域模型来保存数据。我必须添加对多语言的支持,我不想用位置概念污染域模型。

我喜欢在数据库中存在一个带有标题和语言字段的ProductTranslate表,但在我的域名中属于Product实体。

有人知道怎么做到这个吗?

1 个答案:

答案 0 :(得分:10)

这是我使用的,并且首先适用于代码。

定义基础Translation类:

using System;

public abstract class Translation<T> where T : Translation<T>, new()
{

  public Guid Id { get; set; }

  public string CultureName { get; set; }

  protected Translation()
  {
    Id = Guid.NewGuid();
  }

}

定义TranslationCollection类:

using System.Collections.ObjectModel;
using System.Globalization;
using System.Linq;

public class TranslationCollection<T> : Collection<T> where T : Translation<T>, new()
{

  public T this[CultureInfo culture]
  {
    get
    {
      var translation = this.FirstOrDefault(x => x.CultureName == culture.Name);
      if (translation == null)
      {
        translation = new T();
        translation.CultureName = culture.Name;
        Add(translation);
      }

      return translation;
    }
    set
    {
      var translation = this.FirstOrDefault(x => x.CultureName == culture.Name);
      if (translation != null)
      {
        Remove(translation);
      }

      value.CultureName = culture.Name;
      Add(value);
    }
  }

  public T this[string culture]
  {
    get
    {
      var translation = this.FirstOrDefault(x => x.CultureName == culture);
      if (translation == null)
      {
        translation = new T();
        translation.CultureName = culture;
        Add(translation);
      }

      return translation;
    }
    set
    {
      var translation = this.FirstOrDefault(x => x.CultureName == culture);
      if (translation != null)
      {
        Remove(translation);
      }

      value.CultureName = culture;
      Add(value);
    }
  }

  public bool HasCulture(string culture)
  {
    return this.Any(x => x.CultureName == culture);
  }

  public bool HasCulture(CultureInfo culture)
  {
    return this.Any(x => x.CultureName == culture.Name);
  }

}

然后,您可以在实体中使用这些类,例如:

using System;
using System.Globalization;

public class HelpTopic
{

  public Guid Id { get; set; }

  public string Name { get; set; }

  public TranslationCollection<HelpTopicTranslation> Translations { get; set; }

  public string Content
  {
    get { return Translations[CultureInfo.CurrentCulture].Content; }
    set { Translations[CultureInfo.CurrentCulture].Content = value; }
  }

  public HelpTopic()
  {
    Id = Guid.NewGuid();
    Translations = new TranslationCollection<HelpTopicTranslation>();
  }

}

HelpTopicTranslation定义为:

using System;

public class HelpTopicTranslation : Translation<HelpTopicTranslation>
{

  public Guid HelpTopicId { get; set; }

  public string Content { get; set; }

  public HelpTopicTranslation()
  {
    Id = Guid.NewGuid();
  }

}

现在,对于代码的第一个特定方面,请使用以下配置:

using System.Data.Entity.ModelConfiguration;
using Model;

internal class HelpTopicConfiguration : EntityTypeConfiguration<HelpTopic>
{

  public HelpTopicConfiguration()
  {
    Ignore(x => x.Content); // Ignore HelpTopic.Content since it's a 'computed' field.
    HasMany(x => x.Translations).WithRequired().HasForeignKey(x => x.HelpTopicId);
  }

}

并将其添加到您的上下文配置中:

public class TestContext : DbContext
{

  public DbSet<HelpTopic> HelpTopics { get; set; }

  protected override void OnModelCreating(DbModelBuilder modelBuilder)
  {
    modelBuilder.Configurations.Add(new HelpTopicConfiguration());
  }

}

完成所有这些操作后,将生成以下迁移:

using System.Data.Entity.Migrations;

public partial class AddHelpTopicTable : DbMigration
{

  public override void Up()
  {
    CreateTable(
      "dbo.HelpTopics",
      c => new
      {
        Id = c.Guid(false),
        Name = c.String(),
      })
      .PrimaryKey(t => t.Id);

    CreateTable(
      "dbo.HelpTopicTranslations",
      c => new
      {
        Id = c.Guid(false),
        HelpTopicId = c.Guid(false),
        Content = c.String(),
        CultureName = c.String(),
      })
      .PrimaryKey(t => t.Id)
      .ForeignKey("dbo.HelpTopics", t => t.HelpTopicId, true)
      .Index(t => t.HelpTopicId);
  }

  public override void Down()
  {
    DropForeignKey("dbo.HelpTopicTranslations", "HelpTopicId", "dbo.HelpTopics");
    DropIndex("dbo.HelpTopicTranslations", new[] { "HelpTopicId" });
    DropTable("dbo.HelpTopicTranslations");
    DropTable("dbo.HelpTopics");
  }

}

欢迎任何评论和/或改进......