私はEF 4.1を使用しており、列挙型のサポートが不足しているため、適切な回避策を探していました。 intのバッキングプロパティは論理的です。
[Required]
public VenueType Type
{
get { return (VenueType) TypeId; }
set { TypeId = (int) value; }
}
private int TypeId { get; set; }
しかし、どうすればこのプロパティをプライベートにしてもマッピングできますか?言い換えると:
最初にEF 4.1コードを使用してプライベートプロパティをマップするにはどうすればよいですか?
最初にEFコードでプライベートプロパティをマップすることはできません。 protected
に変更して、EntityConfiguration
から継承したクラスで構成してみてください。
編集
変更されました、これを参照してください https://stackoverflow.com/a/13810766/861716
選択した非パブリックプロパティをマップするためにEF 6+で使用できる規則を次に示します(プロパティに[Column]
属性を追加するだけです)。
あなたの場合、TypeIdを次のように変更します。
[Column]
private int TypeId { get; set; }
DbContext.OnModelCreating
では、規則を登録する必要があります。
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Conventions.Add(new NonPublicColumnAttributeConvention());
}
最後に、ここに規約があります:
/// <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;
}
}
別の回避策は、フィールドを内部として設定することです。
[NotMapped]
public dynamic FacebookMetadata {
get
{
return JObject.Parse(this.FacebookMetadataDb);
}
set
{
this.FacebookMetadataDb = JsonConvert.SerializeObject(value);
}
}
///this one
internal string FacebookMetadataDb { get; set; }
ツアーモデルに追加します。
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);
}
モデルに見られるように、プロパティへの読み取りアクセスを許可します。したがって、プライベートセッターを使用してセットアクセスをブロックし、EFにマップする必要がある場合があります。このような。
[Required]
private int TypeId { get; private set; }
これを処理する別の方法は、カスタムエンティティ構成を定義し、そのためのバインディングを追加することです。
クラスにEntityTypeConfigurationから継承するクラスを追加します(これは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");
}
}
}
コンテキストに次を追加します。
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);
}
}
私は自分でこれを見つけたと言えるかもしれませんが、ここで偶然見つけました: https://romiller.com/2012/10/01/mapping-to-private-properties-with-code-first/
上記の@crimboの答え( https://stackoverflow.com/a/21686896/3264286 )を拡張して、プライベートゲッターにパブリックプロパティを含めるように変更します。
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;
}