为什么使用FlagsAttribute定义EntityState枚举

时间:2015-10-01 09:52:06

标签: c# .net entity-framework

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

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

2 个答案:

答案 0 :(得分:4)

  

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

如果您计划将来兼容,那么没有。作者可能会添加一个值,该值可以与当前值之一组合以覆盖更广泛的状态。你最好掩盖。

它们可能没有,但是以这种方式定义会使该选项保持打开状态。

  

他们为什么选择这条路?

也许,所以人们不会认为这些价值是相互排斥的。

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

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 | 428。如果值只是递增的话,它将无效:

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()的工作原理,即在采用这种方法时提供的值更有意义。

答案 1 :(得分:1)

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

例如,在ObjectStateManager中:

IEnumerable<IEntityStateEntry> IEntityStateManager.GetEntityStateEntries(EntityState state)

ObjectContext中的用法:

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

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