为什么EntityState枚举用FlagsAttribute定义

本文关键字:FlagsAttribute 定义 枚举 EntityState 为什么 | 更新日期: 2023-09-27 18:15:33

我正在为我们的应用程序做一个简单的实体更改日志。出现的一个问题是,虽然DbEntityEntry.State属性的枚举值显然是互斥的(参见MSDN),但它是用Flags属性定义的,并且选择的值就好像它们可以组合一样。

假设这些值是互斥的是否安全?他们为什么选择这条路?

为什么EntityState枚举用FlagsAttribute定义

假设这些值是互斥的是否安全?

如果您计划将来的兼容性,则不需要。作者可以添加一个值,该值可以与当前值之一相结合,以覆盖更广泛的状态。你最好屏蔽。

它们可能不存在,但是这样定义会留下一个选择余地。

他们为什么选择这条路?

也许,这样人们就不会认为这两个值是互斥的。

大多数情况下,它允许在单个测试中进行覆盖多个值的掩码测试:

if (state & (EntityState.Deleted | EntityState.Modified | EntityState.Added) != 0)  …

这是有效的,因为enum的值使用标志布局风格,其中每个值都有不同的位设置(或故意定义为另一个):

Detached = 1,
Unchanged = 2,
Added = 4,
Deleted = 8,
Modified = 16

因此,EntityState.Deleted | EntityState.Modified | EntityState.Added具有8 | 16 | 4的值,即28。如果值只是递增,则无法工作:

Detached = 1,
Unchanged = 2,
Added = 3,
Deleted = 4,
Modified = 5

现在EntityState.Deleted | EntityState.Modified | EntityState.Added的值为7,与EntityState.Detached | Entity.Unchanged | Entity.Deleted的值相同。

FlagsAttribute用于提供元数据,表明您采用前一种方法而不是后一种方法,因此屏蔽可以工作。它对类型本身的唯一直接影响是ToString()的工作方式,当采用这种方法时,它提供的值比不使用更有意义。

在内部,EntityState也用于包含/排除多个状态。

例如,在ObjectStateManager中:

IEnumerable<IEntityStateEntry> IEntityStateManager.GetEntityStateEntries(EntityState state)

ObjectContext中的用法:

var entriesAffected = ObjectStateManager.GetObjectStateEntriesCount(EntityState.Added |                   
                                                                    EntityState.Deleted |
                                                                    EntityState.Modified);

从api消费的角度来看,我认为您可以放心地假设实体的实际状态只能是其中一个选项。