2017-07-03 1 views
0

Dans mon application, j'ai de nombreuses entités localisables. La structure de base de données pour ces entités est here. Les types de PK dans certaines tables peuvent être différents (certains sont int, d'autres sont bigint). Cela dépend de combien de données seront stockées dans une table. J'utilise Dapper comme ORM.Référentiel C# et entités localisables

Maintenant, j'ai cette solution (mais quelque chose me dit à l'intérieur que cette solution est mauvaise):

// ENTITY 
public abstract class Entity 
{ 
    public object Id { get; set; } 
} 

public abstract class Entity<TKey> : Entity 
{ 
    public new TKey Id { get; set; } 
} 

// LOCALIZABLE ENTITY 
public abstract class LocalizableEntity<TTranslation> : Entity 
    where TTranslation : EntityTranslation 
{ 
    public ICollection<TTranslation> Translations { get; set; } 
} 

public abstract class LocalizableEntity<TKey, TTranslation> : Entity<TKey> 
    where TTranslation : EntityTranslation 
{ 
    public ICollection<TTranslation> Translations { get; set; } 
} 

// ENTITY TRANSLATION 
public abstract class EntityTranslation 
{ 
    public object LocalizableId { get; set; } 

    public int LanguageId { get; set; } 
} 

public abstract class EntityTranslation<TKey> : EntityTranslation 
{ 
    public new TKey LocalizableId { get; set; } 
} 

// REPOSITORIES 

public class BaseRepository: IRepository, IDisposable 
{ 
    public string ConnectionString { get; set; } 

    // .... 
} 

public abstract class BaseEntityRepository: BaseRepository 
{ 
    protected IDbConnection Connection => _connection ?? (_connection = CreateDbConnection(GetConnectionStringValue(ConnectionString))); 

    protected abstract IDbConnection CreateDbConnection(string connectionString); 

    // SaveEntity<T>(T entity), DeleteEntity(object id) 
} 

public abstract class BaseEntityRepository<TEntity, TKey, TSearchOptions, TLoadOptions> : BaseEntityRepository 
    where TEntity : Entity<TKey> 
    where TSearchOptions : SearchOptions 
    where TLoadOptions : LoadOptions 
{ 
    // GetEntities(TSearchOptions sopts, TLoadOptions lopts), EntityCount(TSearchOptions) ... 
} 

public abstract class BaseLocalizableEntityRepository<TEntity, TKey, TEntityTranslation, TSearchOptions, TLoadOptions> : BaseEntityRepository<TEntity, TSearchOptions, TLoadOptions> 
    where TEntity : Entity<TKey> 
    where TEntityTranslation : EntityTranslation<TKey> 
    where TSearchOptions : SearchOptions 
    where TLoadOptions : LoadOptions 
{ 
    // GetTranslations, SaveTranslation ... 
} 

Est-ce bon ou mauvais? Si c'est mauvais, comment dois-je faire?

+0

La localisation intégrée faite avec les fichiers '.resx' est-elle une option pour vous? Ou est la localisation dont vous avez besoin hautement personnalisable? c'est-à-dire que l'utilisateur doit écrire la traduction. –

+0

@MichaelMairegger J'ai besoin d'une localisation hautement personnalisable. – Alex

+0

Un problème avec ceci est la collation. Si vous avez des langues différentes dans une colonne de base de données, vous risquez de rencontrer des problèmes de tri avec le bon classement pour une langue donnée, car le classement appartient à la colonne. Je ne suis pas au courant d'une solution pour cela. Ce serait bien d'en trouver un, car toutes les alternatives semblent impliquer un SQL dynamique. – bbsimonbb

Répondre

0

Comme vous avez besoin d'une localisation hautement personnalisable, votre solution n'est pas si mauvaise. Je fais la même chose si j'ai besoin de traduction. Mais au lieu d'avoir une autre table par translation de l'entité que j'ai une table unique, à laquelle toutes les entités qui prennent en charge la référence de traduction:

CREATE TABLE Test_Translations 
(
    Language char(10) NOT NULL, 
    TextId int NOT NULL, 
    Value text NOT NULL, 
    CONSTRAINT Test_Translations_Language_TextId_pk PRIMARY KEY (Language, TextId) 
); 

CREATE TABLE Test_LocalizableStrings 
(
    Id int NOT NULL CONSTRAINT Test2_Test1Id_pk primary key 
); 

ALTER TABLE Test_Translations ADD FOREIGN KEY (TextId) REFERENCES Test_LocalizableStrings; 

Resulting Tables

Ensuite, dans les tableaux qui ont besoin d'un support de traduction vient créer une référence clé de Test_LocalizableStrings. Lors de la requête de temps de requête pour TextId et Language.