为什么EntityState枚举用FlagsAttribute定义
本文关键字:FlagsAttribute 定义 枚举 EntityState 为什么 | 更新日期: 2023-09-27 18:15:33
我正在为我们的应用程序做一个简单的实体更改日志。出现的一个问题是,虽然DbEntityEntry.State
属性的枚举值显然是互斥的(参见MSDN),但它是用Flags
属性定义的,并且选择的值就好像它们可以组合一样。
假设这些值是互斥的是否安全?他们为什么选择这条路?
假设这些值是互斥的是否安全?
如果您计划将来的兼容性,则不需要。作者可以添加一个值,该值可以与当前值之一相结合,以覆盖更广泛的状态。你最好屏蔽。
它们可能不存在,但是这样定义会留下一个选择余地。
他们为什么选择这条路?
也许,这样人们就不会认为这两个值是互斥的。
大多数情况下,它允许在单个测试中进行覆盖多个值的掩码测试:
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消费的角度来看,我认为您可以放心地假设实体的实际状态只能是其中一个选项。