1

我一直在使用以下代码,我发现它在很多地方都被推荐用于 Entity Framework 5。

    foreach (var entry in this.ChangeTracker.Entries()
                 .Where(
                      e => e.Entity is IAuditableTable &&
                     (e.State == EntityState.Added) ||
                     (e.State == EntityState.Modified)))
    {
        IAuditableTable e = (IAuditableTable)entry.Entity;
        if (entry.State == EntityState.Added)
        {
            if (e.CreatedBy == 0) 
                e.CreatedBy = 1;
            if (e.CreatedDate == DateTime.MinValue) 
                e.CreatedDate = DateTime.Now;
        }
        if (e.ModifiedBy == 0) 
            e.ModifiedBy = 1;
        if (e.ModifiedDate == DateTime.MinValue) 
            e.ModifiedDate = DateTime.Now;
    }

这适用于 EF5。我只是添加这个:

public partial class Objective : AuditableTable
{

并具有以下内容:

public abstract class AuditableTable : IAuditableTable
{
    public virtual byte[] Version { get; set; }
    public int CreatedBy { get; set; }
    public DateTime CreatedDate { get; set; }
    public int ModifiedBy { get; set; }
    public DateTime ModifiedDate { get; set; }
}

然而。当我有这样的课时:

public partial class Objective : AuditableTable
{
    public Objective()
    {
        this.ObjectiveDetails = new List<ObjectiveDetail>();
    }
    public int ObjectiveId { get; set; }
    public int Number { get; set; }
    public string Text { get; set; }
    public virtual ICollection<ObjectiveDetail> ObjectiveDetails { get; set; }
}

然后代码不起作用,我在线上出现错误:IAuditableTable e = (IAuditableTable)entry.Entity;它尝试将 ObjectiveDetail 类转换为 IAuditableTable:

"Unable to cast object of type 'Models.Core.ObjectiveDetail' to type 'Models.Core.IAuditableTable'."

除非我使 ObjectiveDetail也继承自 IAuditableTable 或添加以下附加检查,否则我无法使检查代码正常工作:if (entry.Entity is IAuditableTable) {停止运行方法主体。

我的问题是。为什么我需要将此辅助检查添加到代码中以使其适用于我,有没有更好的方法可以使此代码仅适用于从 IAuditableTable 继承的类?如果我的类包含其他类而不是不实现 IAuditable 的对象,这e => e.Entity is IAuditableTable似乎不起作用。

这是我的有效代码:

foreach (var entry in this.ChangeTracker.Entries()
             .Where(
                  e => e.Entity is IAuditableTable &&
                 (e.State == EntityState.Added) ||
                 (e.State == EntityState.Modified)))
{
    // I do not know why the following line is needed. My code will not work
    // unless I have the following line for classes that contain classes that
    // do not inherit from IAuditableTable
    if (entry.Entity is IAuditableTable) {
        IAuditableTable e = (IAuditableTable)entry.Entity;
        if (entry.State == EntityState.Added)
        {
            if (e.CreatedBy == 0) 
                e.CreatedBy = 1;
            if (e.CreatedDate == DateTime.MinValue) 
                e.CreatedDate = DateTime.Now;
        }
        if (e.ModifiedBy == 0) 
            e.ModifiedBy = 1;
        if (e.ModifiedDate == DateTime.MinValue) 
            e.ModifiedDate = DateTime.Now;
    }
}
4

1 回答 1

1

问题在于运算符 && 和 || 的默认优先顺序 在 where 方法的条件下。

您当前拥有的条件具有 AND 和 OR 条件,但您没有添加括号来解决运算符 &&,|| 的方式 将得到解决:

this.ChangeTracker.Entries()
         .Where(
              e => e.Entity is IAuditableTable &&
             (e.State == EntityState.Added) ||
             (e.State == EntityState.Modified))

所以默认情况下被解释为:

(e.Entity is IAuditableTable && (e.State == EntityState.Added))
|| (e.State == EntityState.Modified)

如果(实体是 IAuditable 并且已添加)或已修改,这将包括记录。因此,即使它不是IAuditableTable,如果实体被修改,它也会包含在循环中。

对于您想要的逻辑,您需要添加括号来包裹 || 检查实体被添加或修改的条件:

e.Entity is IAuditableTable && 
((e.State == EntityState.Added) || (e.State == EntityState.Modified))

这样,只有在 IAuditable AND(已修改或添加)时才会包含它

于 2013-08-11T09:33:51.623 回答