我正在使用EF 4.1,并且因缺乏枚举支持而寻找一个很好的解决方法。 int的支持属性似乎是合乎逻辑的。
[Required]
public VenueType Type
{
get { return (VenueType) TypeId; }
set { TypeId = (int) value; }
}
private int TypeId { get; set; }
但是如何将此属性设为私有并仍然映射它。换句话说:
如何首先使用EF 4.1代码映射私有属性?
答案 0 :(得分:71)
以下是您可以在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;
}
}
答案 1 :(得分:13)
您无法先在EF代码中映射私有属性。您可以尝试将其更改为protected
并在继承自EntityConfiguration
的类中对其进行配置。
的修改
现在它已更改,请参阅此https://stackoverflow.com/a/13810766/861716
答案 2 :(得分:4)
另一种解决方法可能是将您的字段设置为内部:
[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);
}
答案 3 :(得分:1)
尝试一下。
public class UserAccount
{
private string Username { get; set;}
}
public class UserAccountConfiguration :IEntityTypeConfiguration<UserAccount>
{
public void Configure(EntityTypeBuilder<UserAccount> builder)
{
builder.Property(c => c.Username);
}
}
,然后在DbContext中
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.ApplyConfiguration(new UserAccount.UserAccountConfiguration());
}
答案 4 :(得分:0)
扩展@ 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;
}
答案 5 :(得分:0)
另一种处理方法是定义自定义实体配置并为其添加绑定。
在您的类中添加一个继承自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/
答案 6 :(得分:0)
如您的模型中所示,您授予对该属性的读取权限。因此,您可能希望阻止设置访问并使用私有设置器映射到EF。像这样。
[Required]
private int TypeId { get; private set; }
答案 7 :(得分:0)
如果您喜欢 const express = require("express");
// eslint-disable-next-line no-unused-vars
// const bodyParser = require('body-parser');
const path = require("path");
const app = express();
const port = process.env.PORT || 8080;
app.use(express.static(path.join(__dirname, "build")));
// This route serves the React app
app.get('/', (req, res) => res.sendFile(path.resolve(__dirname, "build", "index.html")));
app.listen(port, () => console.log(`Server listening on port ${port}`));
(像我一样)并且正在使用 EF Core。您可以使用以下方法。
首先,创建一个属性来标记私有或属性:
Attributes
然后,标记您希望保密的属性。
using System;
using System.ComponentModel.DataAnnotations.Schema;
...
[System.AttributeUsage(AttributeTargets.Property, Inherited = true, AllowMultiple = false)]
public sealed class ShadowColumnAttribute : ColumnAttribute
{
public ShadowColumnAttribute() { }
public ShadowColumnAttribute(string name): base(name) { }
}
最后,在您的 public class MyEntity
{
[Key]
public string Id { get; set; }
public bool SomeFlag { get; set; }
public string Name => SomeFlag ? _Name : "SomeOtherName";
[ShadowColumn(nameof(Name))]
string _Name { get; set; }
}
中,将其放入您的 DbContext
方法中:
OnModelCreating