Saltar al contenido

Asignar un diccionario en Entity Framework Code First Approach

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 Columnasí 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 XMLcomo 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.

Te mostramos reseñas y valoraciones

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *