2015-10-01 20 views
7

Tôi đang thực hiện ghi nhật ký thay đổi Thực thể đơn giản cho ứng dụng của chúng tôi. Một câu hỏi phát sinh là trong khi các giá trị liệt kê cho thuộc tính DbEntityEntry.State rõ ràng là loại trừ lẫn nhau (See MSDN), nó được xác định với thuộc tính Flags và các giá trị được chọn như thể chúng có thể được kết hợp.Tại sao liệt kê EntityState được xác định với FlagsAttribute

Có an toàn để giả định rằng các giá trị loại trừ lẫn nhau không? Tại sao họ lại chọn con đường này?

Trả lời

4

Có an toàn để giả định rằng các giá trị này loại trừ lẫn nhau không?

Nếu bạn đang có kế hoạch tương thích trong tương lai, thì không. Các tác giả có thể thêm một giá trị có thể được kết hợp với một trong các giá trị hiện tại để bao quát một trạng thái rộng hơn. Bạn tốt hơn hết mặt nạ.

Chúng có thể không, nhưng được xác định theo cách này để tùy chọn đó mở.

Tại sao họ lại chọn đường dẫn này?

Có lẽ, để mọi người không cho rằng giá trị loại trừ lẫn nhau.

Chủ yếu, nó cho phép một để làm các xét nghiệm mặt nạ đó bao gồm nhiều hơn một giá trị trong một thử nghiệm duy nhất:

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

này hoạt động vì các giá trị cho enum sử dụng một phong cách bố trí cờ nơi từng có bit khác nhau thiết lập (hoặc là cố ý quy định tại các điều khoản của người khác):

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

Bởi vì điều này, EntityState.Deleted | EntityState.Modified | EntityState.Added có giá trị 8 | 16 | 4 đó là 28. Nó sẽ không hoạt động nếu các giá trị mà chỉ tăng lên:

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

Bây giờ EntityState.Deleted | EntityState.Modified | EntityState.Added sẽ có một giá trị của 7 mà là giống như EntityState.Detached | Entity.Unchanged | Entity.Deleted.

FlagsAttribute được sử dụng để cung cấp siêu dữ liệu cho biết bạn đang sử dụng phương pháp tiếp cận cũ hơn là sau, vì vậy mặt nạ có thể hoạt động. Hiệu ứng duy nhất nó có trực tiếp trên chính loại đó là cách hoạt động của ToString(), đó là cung cấp một giá trị có ý nghĩa hơn khi thực hiện phương pháp này hơn là không.

+1

Theo @CodeCaster, nó không phải thuộc tính '[Flags]' cho phép người ta thực hiện các kiểm tra mặt nạ "(http: // stackoverflow.com/questions/8447/what-does-the-flags-enum-thuộc tính-mean-in-c). – haim770

+0

@ haim770 nó không phải. Đó là bố cục kiểu cờ cho phép điều đó. '[Flags]' đánh dấu một enum khi sử dụng bố trí kiểu cờ. –

+1

@JonHanna Bạn có thể xây dựng trên bố cục kiểu cờ không? Hoặc một liên kết sẽ được đánh giá cao. – Alireza

1

Nội bộ, EntityState cũng được sử dụng để bao gồm/loại trừ nhiều tiểu bang.

Ví dụ, trong ObjectStateManager:

IEnumerable<IEntityStateEntry> IEntityStateManager.GetEntityStateEntries(EntityState state) 

Cách sử dụng trong ObjectContext:

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

Từ API tốn-point-of-view, tôi nghĩ bạn có thể giả định rằng tình trạng thực tế của một thực thể chỉ có thể là một trong các tùy chọn.

+1

_ "Đối với [Flags] đó là bắt buộc." _ - không, [chỉ sử dụng cho '[Flags]' là để in giá trị của một enum] (http://stackoverflow.com/questions/8447/what-does- the-flags-enum-attribute-mean-in-c). Nó hoàn toàn là siêu dữ liệu. – CodeCaster

+1

@CodeCaster, Vâng, nó không phải là * yêu cầu * hầu như bất cứ nơi nào bạn đang sử dụng một mặt nạ với Enum. Nhưng trong trường hợp này (và trong hầu như tất cả các trường hợp khác) thì có lý do đó. – haim770

+0

@CodeCaster Tôi đã rất ngạc nhiên khi thấy rằng Flags là không cần thiết cho điều đó, và một ứng dụng mẫu nhanh chóng xác minh quan điểm của bạn. Chỉ cần trong VS2015, tôi nhận được cảnh báo intellisense để làm "Bitwise hoạt động trên enum không được đánh dấu bằng thuộc tính Flags". Cảm ơn bạn – Alireza

Các vấn đề liên quan