【问题标题】:EF Code First Readonly columnEF Code First 只读列
【发布时间】:2011-09-27 17:32:25
【问题描述】:

我首先使用 EF 代码和数据库优先方法。 "with Database.SetInitializer(null);"

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

现在我想做的是从 EF 代码的第一个角度使它只读。 IE。我希望能够从我的应用程序中查看创建日期和修改日期,但我不想修改这些数据。

我尝试在 setter 上使用私有修饰符,但没有成功。当我尝试向表中添加新数据时,它尝试将 DateTime.Max 日期输入到数据库中,这会从 SQL 服务器引发错误。

有什么想法吗?

【问题讨论】:

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


    【解决方案1】:

    您不能使用私有修饰符,因为 EF 本身在加载您的实体时需要设置您的属性,而 Code First 只能在属性具有公共设置器时执行此操作(与可以使用私有设置器的 EDMX 相比 (1), @ 987654322@)。

    您需要做的是将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);
    

    【讨论】:

    • 感谢您的快速回复。 DatabaseGeneratedOption.Identity 和 DatabaseGeneratedOption.Computed 有什么区别?我似乎无法在网上找到有关此的详细信息。 thx 编辑:不要回答我得到了答案:msdn.microsoft.com/en-us/library/…。我会让你知道进展如何,非常感谢
    • 当我将 [DatebaseGenerated(DatabaseGeneratedOption.Identity)] 属性用于我得到的 CreatedDate 属性时,更新数据库:身份列“CreatedDate”必须是数据类型 int、bigint、smallint、tinyint、或十进制或数字,比例为 0,并且限制为不可为空。
    • 我也有同样的问题。有什么解决办法吗?
    • @koraytaylan - 不要将DatabaseGeneratedOption.Identity 用于日期字段。相反,请使用 DatabaseGeneratedOption.Computed,这是 Ladislav 在他的回答中建议的。
    【解决方案2】:

    EF 核心 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;
        }
    }
    

    类 MyContext : DbContext { 公共 DbSet 博客 { 获取;放; }

    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..

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-03-13
      • 2012-09-25
      • 1970-01-01
      • 2012-09-11
      • 2011-11-23
      • 1970-01-01
      相关资源
      最近更新 更多