Использование столбца XML в БД
Итак, сегодня я столкнулся с той же проблемой, и подумав об этом, я нашел классное решение, которым я хотел бы поделиться с сообществом, даже если я опаздываю.По сути, я создал систему упаковки, которая сохраняет данные из Dictionary
в Database
как XML Column
, поэтому позже я также могу запросить XML из БД, если захочу.
Pro этого подхода
- Простота использования
- Быстрое внедрение
- Вы можете использовать словарь
- Вы можете запроситьстолбец XML
Прежде всего, вот кость всех моих моделей:
public abstract class BaseEntity
{
/// <summary>
/// ID of the model
/// </summary>
public int ID { get; set; }
}
Предположим, у меня есть модель, которая содержит Dictionary<string,string>
и String
свойство, которое содержит логику для сериализации и десериализации словаря в XML
, например, следующий фрагмент:
public class MyCoolModel : Base.BaseEntity
{
/// <summary>
/// Contains XML data of the attributes
/// </summary>
public string AttributesData
{
get
{
var xElem = new XElement(
"items",
Attributes.Select(x => new XElement("item", new XAttribute("key", x.Key), new XAttribute("value", x.Value)))
);
return xElem.ToString();
}
set
{
var xElem = XElement.Parse(value);
var dict = xElem.Descendants("item")
.ToDictionary(
x => (string)x.Attribute("key"),
x => (string)x.Attribute("value"));
Attributes = dict;
}
}
//Some other stuff
/// <summary>
/// Some cool description
/// </summary>
[NotMapped]
public Dictionary<string, string> Attributes { get; set; }
}
Затем я реализовал класс BaseMapping
, который наследуется от EntityTypeConfiguration<T>
class BaseMapping<TEntity> : EntityTypeConfiguration<TEntity>
where TEntity : Model.Base.BaseEntity
{
public BaseMapping()
{
//Some basic mapping logic which I want to implement to all my models
}
}
И после пользовательского Mapping
для MyCoolModel
class MyCoolModelMapping
: BaseMapping<Model.MyCoolModel>
{
public MyCoolModelMapping()
{
Property(r => r.AttributesData).HasColumnType("xml");
}
}
Теперь обратите внимание, что когда AttributesData
запрашивается значение *1040*, он просто сериализует словарь, и то же самое происходит, когдаЯ извлекаю данные из БД, и EntityFramework устанавливает данные в поле, которое затем десериализует объект и устанавливает его в dict.
И наконец у меня есть override
OnModelCreating
моего DbContext
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Configurations.Add(new Mappings.BaseMapping<SomeOtherModel>());
modelBuilder.Configurations.Add(new Mappings.MyCoolModelMapping());
//Other logic
}
И это все!Теперь я могу использовать словарь из своей бизнес-логики, и эта «упаковка» обрабатывает все, что нужно для сохранения данных в DB
и извлечения данных из него.