2012-06-21 29 views
23

Tôi muốn biết sự khác nhau giữa việc tạo các lớp có hoặc không sử dụng "hashset" trong hàm tạo.sử dụng hashset trong khung thực thể

Sử dụng mã tiếp cận đầu tiên (4.3) ta có thể tạo mô hình như thế này:

public class Blog 
{ 
    public int Id { get; set; } 
    public string Title { get; set; } 
    public string BloggerName { get; set;} 
    public virtual ICollection<Post> Posts { get; set; } 
    } 

public class Post 
{ 
    public int Id { get; set; } 
    public string Title { get; set; } 
    public DateTime DateCreated { get; set; } 
    public string Content { get; set; } 
    public int BlogId { get; set; } 
    public ICollection<Comment> Comments { get; set; } 
} 

hoặc có thể tạo mô hình như thế này:

public class Customer 
{ 
    public Customer() 
    { 
     BrokerageAccounts = new HashSet<BrokerageAccount>(); 
    } 
    public int Id { get; set; } 
    public string FirstName { get; set; } 
    public ICollection<BrokerageAccount> BrokerageAccounts { get; set; } 
} 

public class BrokerageAccount 
{ 

    public int Id { get; set; } 
    public string AccountNumber { get; set; } 
    public int CustomerId { get; set; } 

} 

được HashSet làm gì ở đây?

tôi có nên sử dụng hashset trong hai mô hình đầu tiên không?

có bài viết nào hiển thị ứng dụng băm không?

Trả lời

12

Tôi khá mới đối với Khung thực thể nhưng đây là sự hiểu biết của tôi. Các loại bộ sưu tập có thể là bất kỳ loại nào triển khai ICollection<T>. Theo quan điểm của tôi, HashSet thường là kiểu thu thập đúng ngữ nghĩa. Hầu hết các bộ sưu tập chỉ nên có một cá thể của một thành viên (không trùng lặp) và HashSet thể hiện tốt nhất điều này. Tôi đã viết các lớp học của tôi như hình dưới đây và điều này đã làm việc tốt cho đến nay. Lưu ý rằng bộ sưu tập được nhập là ISet<T> và bộ cài đặt là riêng tư.

public class Customer 
{ 
    public Customer() 
    { 
     BrokerageAccounts = new HashSet<BrokerageAccount>(); 
    } 
    public int Id { get; set; } 
    public string FirstName { get; set; } 
    public ISet<BrokerageAccount> BrokerageAccounts { get; private set; } 
} 
+1

Tôi hoàn toàn đồng ý. Trong hầu hết các trường hợp, 'HashSet' * là * phù hợp tự nhiên nhất. –

+0

hashset vẫn có vẻ đúng trong EF6.x. Về bản chất, EF sẽ sử dụng hashsets theo cách chính xác này trong quá trình tạo các kiểu db đầu tiên. –

16

Nói chung, tốt nhất nên sử dụng bộ sưu tập thể hiện ý định của bạn tốt nhất. Nếu bạn không có ý định cụ thể để sử dụng các đặc tính độc đáo của HashSet, tôi sẽ không sử dụng nó.

Nó không có thứ tự và không hỗ trợ tra cứu theo chỉ mục. Hơn nữa, nó không thích hợp cho việc đọc tuần tự như các bộ sưu tập khác, và thực tế là nó cho phép bạn thêm cùng một mục nhiều lần mà không tạo bản sao chỉ hữu ích nếu bạn có lý do để sử dụng nó cho điều đó. Nếu đó không phải là ý định của bạn, nó có thể ẩn mã không đúng và gây khó khăn cho việc cô lập.

HashSet chủ yếu hữu ích trong các trường hợp khi thời gian chèn và loại bỏ rất quan trọng, chẳng hạn như khi xử lý dữ liệu. Nó cũng cực kỳ hữu ích để so sánh các bộ dữ liệu (một lần nữa khi xử lý) bằng cách sử dụng các hoạt động như giao nhau, ngoại trừ và công đoàn. Trong bất kỳ tình huống nào khác, khuyết điểm thường lớn hơn những ưu điểm.

Hãy xem xét rằng khi làm việc với các bài đăng trên blog, chèn và xóa khá hiếm so với lượt đọc và bạn thường muốn đọc dữ liệu theo thứ tự cụ thể. Đó là nhiều hơn hoặc ít hơn so với chính xác những gì HashSet là tốt. Rất nghi ngờ rằng bạn sẽ có ý định thêm cùng một bài hai lần, vì bất kỳ lý do nào và tôi không thấy lý do nào bạn sẽ sử dụng các hoạt động dựa trên các bài đăng trong một lớp như thế.

8

HashSet không xác định loại bộ sưu tập sẽ được tạo khi bạn thực sự tìm nạp dữ liệu. Điều này sẽ luôn luôn thuộc loại ICollection như được khai báo.

HashSet được tạo trong hàm dựng là giúp bạn tránh NullReferenceExceptions khi không có bản ghi nào được tìm nạp hoặc tồn tại ở nhiều phía của mối quan hệ. Nó là không có cách nào yêu cầu.

Ví dụ, dựa trên câu hỏi của bạn, khi bạn cố gắng sử dụng một mối quan hệ như ...

var myCollection = Blog.Posts(); 

Nếu không có bài viết tồn tại sau đó myCollection sẽ null.Đó là OK, cho đến khi bạn thành thạo chuỗi sự vật và làm điều gì đó như

var myCollectionCount = Blog.Posts.Count(); 

đó sẽ báo lỗi với một NullReferenceException.

Trong trường hợp như

var myCollection = Customer.BrokerageAccounts(); 
var myCollectionCount = Customer.BrokerageAccounts.Count(); 

sẽ cho kết quả và ICollection rỗng và một số zero. Không có ngoại lệ :-)

+2

Có phải '()' trên các thuộc tính hợp lệ ('Blog.Posts()') không? Không phải nó chỉ là 'Blog.Posts' để truy cập vào lĩnh vực này? – bradlis7

+0

Điều này có vẻ sai. Trình gỡ lỗi cho tôi biết chính xác loại tôi sử dụng trong hàm tạo của mình, ngay cả đối với dữ liệu được tìm nạp từ cơ sở dữ liệu. Điều này cũng được phản ánh trong các hành vi khác nhau khi truy cập vào bộ sưu tập (ví dụ: thông qua DataBinding trên các bộ sưu tập đó). – linac

+1

@linac Nó không phải là HashSet xác định kiểu trả về, mà là định nghĩa của thuộc tính ICollection . HashSet được sử dụng để khởi tạo thuộc tính ICollection. Nếu bạn không khởi tạo thuộc tính trong hàm tạo, trình gỡ lỗi sẽ vẫn hiển thị loại ICollection như được định nghĩa. Không có gì để làm với HashSet !! – NER1808

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