Вы можете использовать TPH для упрощения контекста и действий.
Модели:
public enum PhraseType
{
English,
Spanish
}
public abstract class Phrase
{
public int Id { get; set; }
public string Text { get; set; }
public PhraseType PhraseType { get; set; }
}
public class EnglishPhrase : Phrase {}
public class SpanishPhrase : Phrase {}
DbContext:
public DbSet<Phrase> Phrases { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
//...
modelBuilder.Entity<Phrase>()
.HasDiscriminator(p => p.PhraseType)
.HasValue<EnglishPhrase>(PhraseType.English)
.HasValue<SpanishPhrase>(PhraseType.Spanish);
}
Метод действия:
public IEnumerable<Phrase> GetPhrases(string language)
{
// assuming the language parameter is "english" or "spanish"
var theType = $"YourNamespace.{language}Phrase";
//assuming your models are in the current assembly
Type type = TypeInfo.GetType(theType, true, true);
MethodInfo method = typeof(Queryable).GetMethod("OfType").MakeGenericMethod(type);
var obj = appContext.Phrases.AsQueryable();
var result = method.Invoke(obj, new[] { obj });
return result as IEnumerable<Phrase>;
}
Небольшое объяснение:
Вы используете TPH (Таблица на иерархию), поэтому вам нужно только создать один DbSet
.
Когда вы хотите вернуть все EnglishPhrase
s, которые выможно использовать context.Phrases.OfType<EnglishPhrase>()
, но так как ваш параметр определяет тип, вам нужно использовать отражение, чтобы вызвать правильный метод OfType
.
Вы можете поместить все эти коды отражений в вспомогательный класс, чтобы ваше действие было чище.
В будущем, когда вы захотите добавить больше языков, вам просто нужно отредактировать перечисление PhraseType
и добавить дополнительные HasValue
в ваш Fluent API.Никаких изменений в методе Action не требуется.
Я только что проверил это на своей системе, и это сработало.