EF Code First Readonly专栏

时间:2011-07-03 18:34:51

标签: entity-framework entity-framework-4.1 code-first

我首先使用EF Code和数据库第一种方法。 “使用Database.SetInitializer(null);”

我的表有两列createddate和amendddate。它们由SQL Server使用触发器管理。我们的想法是,当数据输入发生时,这些列通过触发器获取数据。

现在我想做的是从EF Code的第一个角度来看这个只读。即我希望能够从我的应用程序中看到创建日期和已知日期,但我不想修改这些数据。

我尝试在setter上使用私有修饰符,但没有运气。当我尝试向表中添加新数据时,它试图将DateTime.Max日期输入数据库,从而从SQL服务器抛出错误。

有什么想法吗?

2 个答案:

答案 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);

Take a look here..