如何在EF中为POCO实体添加c#自动计算

本文关键字:添加 计算 实体 POCO EF 中为 | 更新日期: 2023-09-27 17:51:17

我在。net 4.5.1中使用DB first EF 6.1.3, T4生成的实体是具有生成的自动属性的POCO类。我想做一些计算(计算int字段实际上)之前保存到数据库。

我当然可以用UPDATE触发器做到这一点,但现在我更喜欢c#算法。我在DBContext中寻找要覆盖的内容,但没有找到任何内容。最接近的赌注是ValidateEntity(...),但这让我觉得它的名字完全不同。(不谈论如何访问实体实例似乎不是微不足道的)

如何以及在哪里完成自动计算之前更新或更好:在属性设置?

如何在EF中为POCO实体添加c#自动计算

您可以做如下操作,即覆盖SaveChanges。

public partial class MyEntities : ObjectContext
{
    /// <summary>
    /// Persists all updates to the data source with the specified System.Data.Objects.SaveOptions.
    /// </summary>
    /// <param name="saveOptions">A System.Data.Objects.SaveOptions value that determines the behavior of the operation.</param>
    /// <returns>The number of objects in an System.Data.EntityState.Added, System.Data.EntityState.Modified, or 
    /// System.Data.EntityState.Deleted state when System.Data.Objects.ObjectContext.SaveChanges() was called.</returns>
    public override int SaveChanges(SaveOptions saveOptions)
    {
        List<Itinerary> itineraryLocations = ItineraryAddedDeletedMonitor.GetItineraryLocations(this);
        AlertManager.ObjectContextSavingChanges(this, null);
        int changes = base.SaveChanges(saveOptions);
        if (ItineraryAddedDeletedMonitor.ProcessItineraryLocations(this, itineraryLocations))
        {
            // new rows have been added
            base.SaveChanges(saveOptions);
        }
        return changes;
    }
}

更新:

要访问实体实例,下面示例中的objectStateEntries获取所有Modified, add和Deleted实体(根据需要更改):

IEnumerable<ObjectStateEntry> objectStateEntries = objectContext.ObjectStateManager.GetObjectStateEntries(EntityState.Modified | EntityState.Added | EntityState.Deleted);
foreach (ObjectStateEntry entry in objectStateEntries)
{
    if (!entry.IsRelationship && entry.Entity.GetType() == typeof(CustomerTransfer) && entry.State == EntityState.Deleted)
    {
        // Do some magic if the entity type is a CustomerTransfer that has been deleted.
    }
}

更新:

…变量objectContext为:

var objectContext = ((IObjectContextAdapter)this).ObjectContext;

例如,您有一个用户,首先使用数据库生成自动属性。在.tt文件中会生成一个User.cs文件。这些都是生成的,所以没有必要更改

你能做的是创建一个新文件来包含元数据类,在这个例子中我将它命名为entityannotations。cs,我之所以这样命名它,是因为你还可以用它来给你的实体属性添加注解。

如果User生成的类(从您现有的数据库生成)具有

 public partial class User
 {   
     public int UserId { get; set; }
     public string UserName { get; set; }
     public string EmailAddress { get; set; }
     public int CalculatedValue {get;set;}
 }

你可以创建这个

[MetadataType(typeof(UserMetadata))]
public partial class User
{
     public int Calculate
     {
        get { return CalculatedValue;}
        set { CalculatedValue = value +1;}
     }
}

然后

public class UserMetadata
{
    //Fields from User requiring annotations
    [EmailAddress]
    public string EmailAddress { get; set; }   
}

我现在使用元数据对生成的实体强制执行电子邮件地址验证。我还使用部分类添加了一个Calculate字段,该字段将从get上生成的类返回CalculatedValue属性,并将CalculatedValue属性设置为setCalculate逻辑的结果

您可以使用SavingChanges事件。如果使用这种技术,您可以查找所需类型和处于所需状态的实体,并对其进行修改。文档中的示例显示了如何查找这些实体。