wake-up-neo.com

zuerst wird der Framework-Code für private Eigenschaftsentitäten zugeordnet

Ich verwende EF 4.1 und suchte nach einem Nice-Workaround für den Mangel an Unterstützung für Aufzählungen. Eine unterstützende Eigenschaft von int scheint logisch. 

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

    private int TypeId { get; set; }

Aber wie kann ich diese Eigenschaft privat machen und trotzdem abbilden? Mit anderen Worten:

Wie kann ich ein Privateigentum zuerst mit EF 4.1-Code zuordnen?

20
Gluip

Sie können private Eigenschaften nicht zuerst in EF-Code zuordnen. Sie können es in protected ändern und in einer von EntityConfiguration geerbten Klasse konfigurieren.
Bearbeiten
Jetzt wird es geändert. Siehe diese https://stackoverflow.com/a/13810766/861716

13

Hier eine Konvention, die Sie in EF 6+ verwenden können, um ausgewählte nicht öffentliche Eigenschaften zuzuordnen (fügen Sie einfach das [Column]-Attribut einer Eigenschaft hinzu).

In Ihrem Fall ändern Sie TypeId in:

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

In Ihrem DbContext.OnModelCreating müssen Sie die Konvention registrieren:

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

Schließlich ist hier die Konvention:

/// <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;
    }
}
70
crimbo

Eine andere Problemumgehung könnte darin bestehen, Ihr Feld als intern festzulegen:

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

    ///this one
    internal string FacebookMetadataDb { get; set; }

und füge es dem Tourmodell hinzu:

    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);
    }
4
Jean F.

Wie in Ihrem Modell gezeigt, gewähren Sie Lesezugriff auf die Eigenschaft. Vielleicht möchten Sie den gesetzten Zugriff blockieren und EF mit einem privaten Setter zuordnen. So was.

[Required]
private int TypeId { get; private set; }
0
Jonathan Ramos

Eine andere Möglichkeit, dies zu behandeln, besteht darin, eine benutzerdefinierte Entitätskonfiguration zu definieren und dafür eine Bindung hinzuzufügen. 

Fügen Sie in Ihrer Klasse eine Klasse hinzu, die von EntityTypeConfiguration erbt. (Dies befindet sich in 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");
            }
        }
    }

Fügen Sie in Ihrem Kontext Folgendes hinzu:

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);
    }
}

Ich wünschte, ich könnte sagen, dass ich das alleine gefunden habe, aber ich bin darauf gestoßen: https://romiller.com/2012/10/01/mapping-to-private-properties-with-code-first/

0
rahicks

@ Crimbo's Antwort weiter oben ( https://stackoverflow.com/a/21686896/3264286 ), hier ist meine Änderung, öffentliche Eigenschaften mit privaten Gettern einzuschließen:

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;
}
0
Delorian