2013-03-18 45 views
8

Tôi có nhiều trường hợp hai lớp ChildrenAnimal có mối quan hệ thực thể nhiều đối tượng.Tôi sử dụng cấu trúc dữ liệu nào ở đây?

Tôi muốn có cấu trúc dữ liệu như vậy được đưa ra Children Tôi có thể nhận danh sách Animal được ánh xạ tới nó và ngược lại. Đối với bất kỳ Animal nào, tôi có thể nhận danh sách Children được ánh xạ tới nó.

Tôi cần cấu trúc dữ liệu này để đồng thời sao cho có thể truy cập bất kỳ chuỗi nào.

Vì vậy, đưa ra một bản đồ ví dụ:

Child1 -> Animal1 
Child1 -> Animal2 
Child1 -> Animal3 
Child2 -> Animal2 
Child2 -> Animal3 
Child3 -> Animal3 

Truy vấn cho Child1 Tôi muốn để có được một danh sách trả về: [ Animal1, Animal2, Animal2 ].

Truy vấn Animal2 Tôi muốn nhận danh sách được trả lại: [ Child2, Child3 ]. Cách duy nhất tôi có thể nghĩ để làm điều này là sử dụng từ điển và danh sách cho mỗi mục trong từ điển này (cả Động vật và Trẻ em), nhưng sau đó tôi sẽ phải xử lý khóa đồng bộ danh sách. .

+2

Bạn thực sự cần thêm bảng ánh xạ, chẳng hạn như AnimalChildren để giúp xóa nhiều thứ đó với nhiều người. – mattytommo

+0

Sử dụng danh từ số nhiều cho tên lớp là kiểu xấu; xem xét đổi tên lớp của bạn thành "Trẻ em". –

+0

Mối quan hệ nhiều-nhiều này có thay đổi theo thời gian hay một khi bạn có một bộ trẻ em và động vật, quan hệ của chúng có được sửa chữa không? Nó là dễ dàng hơn nhiều để làm cho một thread an toàn hoạt động nếu không có viết. –

Trả lời

7

Tôi nghĩ bạn phải chia nhỏ cấu trúc dữ liệu của mình thành ba cấp.

Child <- ChildToAnimalRelation -> Animal 

Vì vậy ChildAnimal cả hai đều có bộ sưu tập của ChildToAnimalRelation

public class ChildToAnimalRelation 
{ 
    public Child Child { get; set; } 
    public Animal Animal { get; set; } 
} 

Bắt một động vật trẻ em sẽ được thực hiện như sau:

var children = currentAnimal.ChildToAnimalRelations.Select(r => r.Child); 

ngược lại:

var animals = currentChild.ChildToAnimalRelations.Select(r => r.Animal); 
+0

Hãy xem xét rằng bằng cách chia tách theo cách này giữa các tầng khác nhau, bất kỳ loại cập nhật nào trong khung công tác của bạn đều phải chú ý đến việc cập nhật từng cấp độ quan tâm. – Tigran

+0

Hai dòng nhận được động vật hoặc trẻ em bạn đặt vào cuối câu trả lời của bạn sẽ trả về * tất cả * động vật hoặc trẻ em, không chỉ một lần cho một đối tác nhất định. Bạn sẽ phải thêm một mệnh đề ở trước ... – Spontifixus

+0

@Spontifixus: bộ sưu tập nằm trên chính bản thân * và không chứa * tất cả * quan hệ. Tôi đã chỉnh sửa tên biến để tránh nhầm lẫn. –

2

Làm thế nào về việc sử dụng danh sách và sau đó sử dụng LINQ cho truy vấn? Một triển khai có thể có:

List<Tuple<string, string>> allItems=new ... 
allItems.Add(Tuple.Create("Child1", "Animal1"); 
... 
var child1RelatedItems=allItems.Where(entry =>entry.Item1=="Child1"); 
var animal1RelatedItems=allItems.Where(entry =>entry.Item2=="Animal1"); 
... 
+0

Cho dù điều này sẽ đủ phụ thuộc chủ yếu vào đầu vào. Hiệu quả của nó liên quan trực tiếp đến bao nhiêu quan hệ có (thay vì bao nhiêu trẻ em hoặc động vật). Nếu ánh xạ giữa hai là dày đặc, và bạn có rất nhiều cả hai ... oi. Nếu nó chỉ là một cặp vợ chồng, điều này sẽ làm. – cHao

+0

ChildToAnimalRelation có giải quyết được vấn đề này không? – David

+2

Có lẽ không phải một mình. Lớp ChildToAnimalRelation đang phục vụ cùng mục đích với các bộ dữ liệu của bạn. Bạn không đạt được gì ngoài nhiều tên mô tả hơn. Câu trả lời khác đang làm là gắn các mối quan hệ với mỗi đứa trẻ và động vật, vì vậy nó chỉ phải lặp lại những cái tương ứng với điều đó. – cHao

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