EntityFramework CreatedOn 属性 只能在 SaveChanges 方法中设置
EntityFramework CreatedOn property can be set only in SaveChanges method
我有一个名为 Entity
的模型对象,我将其用作我的基础 class。
[Serializable]
public class Entity
{
[Key]
public int Id { get; set; }
[Required]
public DateTime? ModifiedOn { get; set; }
[Required]
public DateTime? CreatedOn { get; set; }
}
然后我像这样覆盖了SaveChanges
方法,所以每次我创建新记录时CreatedOn
属性都会自动设置。
public override int SaveChanges()
{
ObjectContext context = ((IObjectContextAdapter)this).ObjectContext;
foreach (var entry in context.ObjectStateManager.GetObjectStateEntries(EntityState.Added | EntityState.Modified))
{
var entity = entry.Entity as Entity;
if(entry.State == EntityState.Added)
{
entity.CreatedOn = DateTime.UtcNow;
}
entity.ModifiedOn = DateTime.UtcNow;
}
return base.SaveChanges();
}
我的问题是如何防止在其他地方设置 CreatedOn
和 ModifiedOn
属性,SaveChanges
方法除外。例如,这是不允许的:
Entity entity = new Entity { CreatedOn = DateTime.UtcNow, ModifiedOn = DateTime.UtcNow };
context.Entities.Add(entity);
context.SaveChanges();
有两种方法可以做到这一点
1)使您的 DbContext 成为嵌套的 class(这样您就可以访问外部 class 的私有字段)
2)使用反射(正如@Hamlet Hakobyan 所建议的那样)
示例 1
using System;
using System.ComponentModel.DataAnnotations;
using System.Data.Entity;
using System.Data.Entity.Core.Objects;
using System.Data.Entity.Infrastructure;
namespace ConsoleApplication3
{
class Program
{
public static void Main()
{
Entity.MyContext context = new Entity.MyContext();
context.Entities.Add(new Entity());
// context.Entities.Add(new Entity() { Created = DateTime.Now }); //Does not compile
context.SaveChanges();
}
}
[Serializable]
public class Entity
{
[Key]
public int Id { get; set; }
[Required]
public DateTime? Created { get; private set; }
public class MyContext : DbContext
{
public DbSet<Entity> Entities { get; set; }
public override int SaveChanges()
{
ObjectContext context = ((IObjectContextAdapter)this).ObjectContext;
foreach (var entry in context.ObjectStateManager.GetObjectStateEntries(EntityState.Added | EntityState.Modified))
{
var entity = entry.Entity as Entity;
if (entry.State == EntityState.Added)
entity.Created = DateTime.Now;
}
return base.SaveChanges();
}
}
}
}
示例 2
using System;
using System.ComponentModel.DataAnnotations;
using System.Data.Entity;
using System.Data.Entity.Core.Objects;
using System.Data.Entity.Infrastructure;
namespace ConsoleApplication3
{
class Program
{
public static void Main()
{
MyContext context = new MyContext();
context.Entities.Add(new Entity()); // CreatedOn = DateTime.Now does not compile
context.SaveChanges();
Console.ReadLine();
}
}
public class MyContext : DbContext
{
public DbSet<Entity> Entities { get; set; }
public override int SaveChanges()
{
ObjectContext context = ((IObjectContextAdapter)this).ObjectContext;
foreach (var entry in context.ObjectStateManager.GetObjectStateEntries(EntityState.Added | EntityState.Modified))
{
var entity = entry.Entity as Entity;
if (entry.State == EntityState.Added)
entity.GetType().GetProperty("CreatedOn").SetValue(entity, DateTime.Now);
}
return base.SaveChanges();
}
}
[Serializable]
public class Entity
{
[Key]
public int Id { get; set; }
[Required]
public DateTime? CreatedOn { get; private set; }
}
}
我有一个名为 Entity
的模型对象,我将其用作我的基础 class。
[Serializable]
public class Entity
{
[Key]
public int Id { get; set; }
[Required]
public DateTime? ModifiedOn { get; set; }
[Required]
public DateTime? CreatedOn { get; set; }
}
然后我像这样覆盖了SaveChanges
方法,所以每次我创建新记录时CreatedOn
属性都会自动设置。
public override int SaveChanges()
{
ObjectContext context = ((IObjectContextAdapter)this).ObjectContext;
foreach (var entry in context.ObjectStateManager.GetObjectStateEntries(EntityState.Added | EntityState.Modified))
{
var entity = entry.Entity as Entity;
if(entry.State == EntityState.Added)
{
entity.CreatedOn = DateTime.UtcNow;
}
entity.ModifiedOn = DateTime.UtcNow;
}
return base.SaveChanges();
}
我的问题是如何防止在其他地方设置 CreatedOn
和 ModifiedOn
属性,SaveChanges
方法除外。例如,这是不允许的:
Entity entity = new Entity { CreatedOn = DateTime.UtcNow, ModifiedOn = DateTime.UtcNow };
context.Entities.Add(entity);
context.SaveChanges();
有两种方法可以做到这一点
1)使您的 DbContext 成为嵌套的 class(这样您就可以访问外部 class 的私有字段)
2)使用反射(正如@Hamlet Hakobyan 所建议的那样)
示例 1
using System;
using System.ComponentModel.DataAnnotations;
using System.Data.Entity;
using System.Data.Entity.Core.Objects;
using System.Data.Entity.Infrastructure;
namespace ConsoleApplication3
{
class Program
{
public static void Main()
{
Entity.MyContext context = new Entity.MyContext();
context.Entities.Add(new Entity());
// context.Entities.Add(new Entity() { Created = DateTime.Now }); //Does not compile
context.SaveChanges();
}
}
[Serializable]
public class Entity
{
[Key]
public int Id { get; set; }
[Required]
public DateTime? Created { get; private set; }
public class MyContext : DbContext
{
public DbSet<Entity> Entities { get; set; }
public override int SaveChanges()
{
ObjectContext context = ((IObjectContextAdapter)this).ObjectContext;
foreach (var entry in context.ObjectStateManager.GetObjectStateEntries(EntityState.Added | EntityState.Modified))
{
var entity = entry.Entity as Entity;
if (entry.State == EntityState.Added)
entity.Created = DateTime.Now;
}
return base.SaveChanges();
}
}
}
}
示例 2
using System;
using System.ComponentModel.DataAnnotations;
using System.Data.Entity;
using System.Data.Entity.Core.Objects;
using System.Data.Entity.Infrastructure;
namespace ConsoleApplication3
{
class Program
{
public static void Main()
{
MyContext context = new MyContext();
context.Entities.Add(new Entity()); // CreatedOn = DateTime.Now does not compile
context.SaveChanges();
Console.ReadLine();
}
}
public class MyContext : DbContext
{
public DbSet<Entity> Entities { get; set; }
public override int SaveChanges()
{
ObjectContext context = ((IObjectContextAdapter)this).ObjectContext;
foreach (var entry in context.ObjectStateManager.GetObjectStateEntries(EntityState.Added | EntityState.Modified))
{
var entity = entry.Entity as Entity;
if (entry.State == EntityState.Added)
entity.GetType().GetProperty("CreatedOn").SetValue(entity, DateTime.Now);
}
return base.SaveChanges();
}
}
[Serializable]
public class Entity
{
[Key]
public int Id { get; set; }
[Required]
public DateTime? CreatedOn { get; private set; }
}
}