Investigamos por el mundo on line y así brindarte la respuesta para tu dilema, si continúas con alguna inquietud puedes dejarnos la duda y te responderemos con gusto, porque estamos para servirte.
Solución:
Actualmente, Entity Framework no admite la asignación de un diccionario de forma nativa.
Consulte lo siguiente para obtener más información y soluciones alternativas:
Entity Framework 4 POCO con diccionario
EF Code First: diccionario de mapas o tipo personalizado como nvarchar
http://social.msdn.microsoft.com/Forums/en-US/adonetefx/thread/a51ba903-2b8b-448e-8677-d140a0b43e89/
EF Core 2.1 introdujo una nueva característica llamada conversión de valor:
Los convertidores de valores permiten convertir valores de propiedad al leer o escribir en la base de datos.
Esta función simplifica en gran medida el enfoque de serialización mencionado en las respuestas anteriores, lo que significa que la introducción de una propiedad “auxiliar” adicional y el marcado de la propiedad de su diccionario como [NotMapped]
se vuelve innecesario.
Aquí hay algunas líneas de código adaptadas a su caso (tenga en cuenta que estoy usando Json.NET, pero siéntase libre de usar el serializador de su elección):
using System.Collections.Generic;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
namespace My.Name.Space
public class MyEntity
public int Id get; set;
public Dictionary LeaveEntitlementDetails get; set;
public class MyEntityConfiguration : IEntityTypeConfiguration
public void Configure(EntityTypeBuilder builder)
builder.ToTable("MyEntity");
builder.HasKey(e => e.Id);
builder
.Property(e => e.LeaveEntitlementDetails)
.IsRequired()
.HasConversion(
v => JsonConvert.SerializeObject(v),
v => v == null
? new Dictionary() // fallback
: JsonConvert.DeserializeObject>(v)
);
Usando una columna XML en DB
Así que hoy me encontré con el mismo problema y, después de pensarlo, encontré una solución genial que me gustaría compartir con la comunidad incluso si llego tarde. Básicamente, he creado un sistema de envoltura que guarda los datos en el Dictionary
al Database
como XML Column
así que más tarde también puedo consultar el XML de la base de datos si quiero.
Pro de este enfoque
- Fácil de usar
- Implementación rápida
- Puedes usar el diccionario
- Puede consultar la columna XML
En primer lugar, aquí está el hueso de todos mis modelos:
public abstract class BaseEntity
///
/// ID of the model
///
public int ID get; set;
Supongamos que tengo un modelo que contiene un Dictionary
y un String
propiedad que contiene la lógica para serializar y deserializar el diccionario en XML
como el siguiente fragmento:
public class MyCoolModel : Base.BaseEntity
///
/// Contains XML data of the attributes
///
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
///
/// Some cool description
///
[NotMapped]
public Dictionary Attributes get; set;
Entonces he implementado un BaseMapping
clase que hereda de EntityTypeConfiguration
class BaseMapping : EntityTypeConfiguration
where TEntity : Model.Base.BaseEntity
public BaseMapping()
//Some basic mapping logic which I want to implement to all my models
Y después de una costumbre Mapping
por MyCoolModel
class MyCoolModelMapping
: BaseMapping
public MyCoolModelMapping()
Property(r => r.AttributesData).HasColumnType("xml");
Ahora observe que cuando AttributesData
el valor es solicitado por EntityFramework
simplemente serializa el diccionario y lo mismo sucede cuando recupero datos de la base de datos y EntityFramework establece los datos en el campo, que luego deserializa el objeto y lo establece en el dict.
y finalmente tengo override
los OnModelCreating
de mi DbContext
protected override void OnModelCreating(DbModelBuilder modelBuilder)
base.OnModelCreating(modelBuilder);
modelBuilder.Configurations.Add(new Mappings.BaseMapping());
modelBuilder.Configurations.Add(new Mappings.MyCoolModelMapping());
//Other logic
¡Y eso es! Ahora puedo usar el diccionario de mi lógica comercial y este “envoltorio” maneja todo lo necesario para guardar los datos en el DB
y recuperar los datos de él.