initial hasconversion framework enum data entity-framework ef-code-first private-members

entity framework - hasconversion - mapeo de la entidad de propiedad privada código de marco primero



entity framework core initial data (6)

Estoy usando EF 4.1 y busqué una buena solución para la falta de soporte de enumeración. Una propiedad de respaldo de int parece lógica.

[Required] public VenueType Type { get { return (VenueType) TypeId; } set { TypeId = (int) value; } } private int TypeId { get; set; }

Pero, ¿cómo puedo hacer que esta propiedad sea privada y aún mapearla? En otras palabras:

¿Cómo puedo mapear una propiedad privada usando el código EF 4.1 primero?


Aquí hay una convención que puede usar en EF 6+ para asignar propiedades no públicas seleccionadas (solo agregue el atributo [Column] a una propiedad).

En su caso, cambiaría TypeId a:

[Column] private int TypeId { get; set; }

En su DbContext.OnModelCreating , deberá registrar la convención:

protected override void OnModelCreating(DbModelBuilder modelBuilder) { modelBuilder.Conventions.Add(new NonPublicColumnAttributeConvention()); }

Finalmente, aquí está la convención:

/// <summary> /// Convention to support binding private or protected properties to EF columns. /// </summary> public sealed class NonPublicColumnAttributeConvention : Convention { public NonPublicColumnAttributeConvention() { Types().Having(NonPublicProperties) .Configure((config, properties) => { foreach (PropertyInfo prop in properties) { config.Property(prop); } }); } private IEnumerable<PropertyInfo> NonPublicProperties(Type type) { var matchingProperties = type.GetProperties(BindingFlags.SetProperty | BindingFlags.GetProperty | BindingFlags.NonPublic | BindingFlags.Instance) .Where(propInfo => propInfo.GetCustomAttributes(typeof(ColumnAttribute), true).Length > 0) .ToArray(); return matchingProperties.Length == 0 ? null : matchingProperties; } }


Como se ve en su modelo, usted otorga acceso de lectura a la propiedad. Así que tal vez quiera bloquear el acceso a los conjuntos y asignarlos a EF utilizando un configurador privado. Me gusta esto.

[Required] private int TypeId { get; private set; }


Extendiendo la respuesta de @crimbo arriba ( https://.com/a/21686896/3264286 ), aquí está mi cambio para incluir propiedades públicas con captadores privados:

private IEnumerable<PropertyInfo> NonPublicProperties(Type type) { var matchingProperties = type.GetProperties(BindingFlags.SetProperty | BindingFlags.GetProperty | BindingFlags.NonPublic | BindingFlags.Instance) .Where(propInfo => propInfo.GetCustomAttributes(typeof(ColumnAttribute), true).Length > 0) .Union( type.GetProperties(BindingFlags.SetProperty | BindingFlags.GetProperty | BindingFlags.Public | BindingFlags.Instance) .Where(propInfo => propInfo.GetCustomAttributes(typeof(ColumnAttribute), true).Length > 0 && propInfo.GetGetMethod().IsNull()) ) .ToArray(); return matchingProperties.Length == 0 ? null : matchingProperties; }


Otra forma de manejar esto es definir una configuración de entidad personalizada y agregar un enlace para eso.

En su clase, agregue una clase que herede de EntityTypeConfiguration (esto se puede encontrar en System.Data.Entity.ModelConfiguration)

public partial class Report : Entity<int> { //Has to be a property private string _Tags {get; set;} [NotMapped] public string[] Tags { get => _Tags == null ? null : JsonConvert.DeserializeObject<string[]>(_Tags); set => _Tags = JsonConvert.SerializeObject(value); } [MaxLength(100)] public string Name { get; set; } [MaxLength(250)] public string Summary { get; set; } public string JsonData { get; set; } public class ReportConfiguration: EntityTypeConfiguration<Report> { public ReportConfiguration() { Property(p => p._tags).HasColumnName("Tags"); } } }

En su contexto agregue lo siguiente:

using Models.ReportBuilder; public partial class ReportBuilderContext:DbContext { public DbSet<Report> Reports { get; set; } protected override void OnModelCreating(DbModelBuilder modelBuilder) { modelBuilder.Configurations.Add(new Report.ReportConfiguration()); base.OnModelCreating(modelBuilder); } }

Ojalá pudiera decir que encontré esto por mi cuenta, pero lo encontré aquí: https://romiller.com/2012/10/01/mapping-to-private-properties-with-code-first/


Otra solución podría ser establecer su campo como interno:

[NotMapped] public dynamic FacebookMetadata { get { return JObject.Parse(this.FacebookMetadataDb); } set { this.FacebookMetadataDb = JsonConvert.SerializeObject(value); } } ///this one internal string FacebookMetadataDb { get; set; }

y agregarlo al modelo de tour:

protected override void OnModelCreating(DbModelBuilder modelBuilder) { modelBuilder.Conventions.Remove<System.Data.Entity.ModelConfiguration.Conventions.ManyToManyCascadeDeleteConvention>(); ///here modelBuilder.Entity<FacebookPage>().Property(p => p.FacebookMetadataDb); base.OnModelCreating(modelBuilder); }


No se pueden asignar propiedades privadas en el código EF primero. Puede intentar cambiarlo a protected y configurarlo en una clase heredada de EntityConfiguration .
Editar
Ahora se ha cambiado, consulte este https://.com/a/13810766/861716