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

xur*_*dev 5 entity-framework localization entity-framework-4

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

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

有人知道如何得到这个?

Jul*_*lin 11

这是我使用的,并且首先与代码一起使用.

定义基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();
  }

}
Run Code Online (Sandbox Code Playgroud)

定义一个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);
  }

}
Run Code Online (Sandbox Code Playgroud)

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

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>();
  }

}
Run Code Online (Sandbox Code Playgroud)

随着HelpTopicTranslation定义为:

using System;

public class HelpTopicTranslation : Translation<HelpTopicTranslation>
{

  public Guid HelpTopicId { get; set; }

  public string Content { get; set; }

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

}
Run Code Online (Sandbox Code Playgroud)

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

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);
  }

}
Run Code Online (Sandbox Code Playgroud)

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

public class TestContext : DbContext
{

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

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

}
Run Code Online (Sandbox Code Playgroud)

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

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");
  }

}
Run Code Online (Sandbox Code Playgroud)

欢迎提出任何意见和/或改进......

  • 我制作了一个测试应用程序来试试这个。效果很好。对共同需求的非常优雅的解决方案。谢谢朱利安。 (2认同)