我首先使用EF Code和数据库第一种方法。 “使用Database.SetInitializer(null);”
我的表有两列createddate和amendddate。它们由SQL Server使用触发器管理。我们的想法是,当数据输入发生时,这些列通过触发器获取数据。
现在我想做的是从EF Code的第一个角度来看这个只读。即我希望能够从我的应用程序中看到创建日期和已知日期,但我不想修改这些数据。
我尝试在setter上使用私有修饰符,但没有运气。当我尝试向表中添加新数据时,它试图将DateTime.Max日期输入数据库,从而从SQL服务器抛出错误。
有什么想法吗?
答案 0 :(得分:35)
您不能使用私有修饰符,因为EF本身需要在加载实体时设置属性,而Code First只能在属性具有公共设置器时执行此操作(与可以使用私有设置器的EDMX相比(1) ,(2))。
您需要做的是将CreatedDate
标记为DatabaseGeneratedOption.Identity
,将AmendDate
标记为DatabaseGeneratedOption.Computed
。这将允许EF正确加载数据库中的数据,在插入或更新后重新加载数据,以便该实体在您的应用程序中是最新的,同时它不允许您更改应用程序中的值,因为设置的值应用程序永远不会传递给数据库。从面向对象的角度来看,它不是一个非常好的解决方案,但从功能的角度来看,它正是你想要的。
您可以使用数据注释来执行此操作:
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public DateTime CreatedDate { get; set; }
[DatabaseGenerated(DatabaseGeneratedOption.Computed)]
public DateTime AmendDate { get; set; }
或者在导出的上下文中使用OnModelCreating
覆盖中的流畅API:
modelBuilder.Entity<YourEntity>()
.Property(e => e.CreatedDate)
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
modelBuilder.Entity<YourEntity>()
.Property(e => e.AmendDate)
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.Computed);
答案 1 :(得分:1)
EF core 1.1或更高版本是,您可以在poco类中使用只读属性。您需要做的是使用后备场。
public class Blog
{
private string _validatedUrl;
public int BlogId { get; set; }
public string Url
{
get { return _validatedUrl; }
}
public void SetUrl(string url)
{
using (var client = new HttpClient())
{
var response = client.GetAsync(url).Result;
response.EnsureSuccessStatusCode();
}
_validatedUrl = url;
}
}
Class MyContext:DbContext { 公共DbSet博客{get;组; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Blog>()
.Property(b => b.Url)
.HasField("_validatedUrl");
}
}
流利的api ...
modelBuilder.Entity<Blog>()
.Property(b => b.Url)
.HasField("_validatedUrl")
.UsePropertyAccessMode(PropertyAccessMode.Field);