I am using EF 4.1 and was look for a nice workaround for the lack of enum support. A backing property of int seems logical.
[Required]
public VenueT
Here's a convention you can use in EF 6+ to map selected non-public properties (just add the [Column]
attribute to a property).
In your case, you'd change TypeId to:
[Column]
private int TypeId { get; set; }
In your DbContext.OnModelCreating
, you'll need to register the convention:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Conventions.Add(new NonPublicColumnAttributeConvention());
}
Finally, here's the convention:
/// <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;
}
}
Another way to handle this is to defines a custom entity configuration and add a binding for that.
In your class add a class that inherits from EntityTypeConfiguration (This can be found 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");
}
}
}
In your context add the following:
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);
}
}
Wish I could say I found this on my own, but I stumbled upon it here:https://romiller.com/2012/10/01/mapping-to-private-properties-with-code-first/
Try this.
public class UserAccount
{
private string Username { get; set;}
}
public class UserAccountConfiguration :IEntityTypeConfiguration<UserAccount>
{
public void Configure(EntityTypeBuilder<UserAccount> builder)
{
builder.Property(c => c.Username);
}
}
and then in DbContext
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.ApplyConfiguration(new UserAccount.UserAccountConfiguration());
}
As seen in your model you grant read access to the property. So maybe you want to block set access and map to EF using a private setter. Like this.
[Required]
private int TypeId { get; private set; }
Extending @crimbo's answer above ( https://stackoverflow.com/a/21686896/3264286 ), here's my change to include public properties with private getters:
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;
}
you can't map private properties in EF code first. You can try it changing it in to protected
and configuring it in a class inherited from EntityConfiguration
.
Edit
Now it is changed , See this https://stackoverflow.com/a/13810766/861716