2012-10-20 30 views
6

Tôi đã tìm thấy rất nhiều câu hỏi tương tự ở đây, nhưng không có câu hỏi nào trong số đó dường như giúp tôi giải quyết vấn đề của mình. Thuộc tính api & không giúp ích gì. Cơ sở dữ liệu đã được tạo ra, nhưng khi thêm một đối tượng vào nó, nó đã bị hỏng. Tôi muốn có một lớp học có một bộ sưu tập của chính nó. Dưới đây là đoạn code tôi có:Mã Đầu tiên - Tự tham khảo một đến nhiều mối quan hệ

[Table("UObjects")] 
public class UObject 
{ 
    [Key] 
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)] 
    [Browsable(false)] 
    public long ID { get; set; } 
    public string Name { get; set; } 
    [Browsable(false)] 
    public long? ParentID { get; set; } 

    public virtual UObject UParent { get; set; } 
    [Browsable(false)] 
    public virtual ICollection<UObject> UObjects { get; set; } 
} 


public class MyContext : DbContext 
{ 
    public DbSet<UObject> UObjects { get; set; } 

    protected override void OnModelCreating(DbModelBuilder modelBuilder) 
    { 
     // This fluent API didn't help 
     //modelBuilder.Entity<UObject>() 
     //  .HasOptional(u => u.UParent) 
     //  .WithMany(u => u.UObjects) 
     //  .HasForeignKey(u => u.ParentID); 

     //modelBuilder.Entity<UObject>() 
     //  .HasOptional(u => u.UParent) 
     //  .WithMany(u => u.UObjects) 
     //  .Map(c => 
     //  { 
     //   c.MapKey("ParentID"); 
     //   c.ToTable("UObjects"); 
     //  }); 
    } 
} 

Đĩa hát trong cơ sở dữ liệu là như thế này:

ID | Name  | ParentID 
------------------------------------ 
1 | First  | 0 
2 | SubFirst | 1 
3 | SubSecond | 1 
4 | SubThird | 2 
5 | SubFourth | 2 

Vậy làm thế nào đối tượng của tôi nên xem xét sau khi tải các đối tượng là tiếp theo:

- First 
     - SubFirst 
     - SubThird 
     - SubFourth 
     - SubSecond 

Nhưng mọi đối tượng có một bộ sưu tập trống. Tôi nên làm gì để nó hoạt động bình thường?

+0

kiểm tra http://stackoverflow.com/questions/10421351/many-to-many-relationship-between-entities-of-same-type-in-mvc3/10422172#10422172 – Shyju

+0

đã thử điều này rồi. Nó tạo ra cơ sở dữ liệu nhưng nó đổ vỡ khi thêm đối tượng mới và gọi SaveChanges() – GaaRa

+5

"* nó bị hỏng *" không thực sự là một mô tả vấn đề tốt. 1) Ngoại lệ chính xác là gì? 2) Bạn đã chạy truy vấn nào khi bạn nạp các thực thể với các bộ sưu tập rỗng? 3) Tại sao bạn có một 'ParentID' của' 0' trong hàng cơ sở dữ liệu đầu tiên? Nó vi phạm ràng buộc tham chiếu (không có hàng nào có 'ID' 0). Hoặc bạn có nghĩa là 'NULL'? – Slauma

Trả lời

-3
  1. Trang trí thuộc tính UParent của bạn bằng thuộc tính khóa ngoại và? vì nó có thể được nullable

[ForeignKey("ParentID")] public virtual UObject? UParent { get; set; }

  1. Trong cơ sở dữ liệu: Set ParentId giá trị cho 'NULL' nếu không có cha mẹ.
+2

? không hợp lệ, vì UObject là một lớp, không phải là một loại giá trị. –

5

Bạn chỉ cần đề cập đến tự tài liệu tham khảo bằng cách sửa chữa trên sân hơn là điều hướng bất động sản như thế này:

[ForeignKey("UParent")] // EF need for self reference 
public long? ParentID { get; set; } 

Và trong constructor khởi tạo các thuộc tính định hướng như thế này:

public UObject()  
    { 
     // this is necessary otherwise EF will throw null object reference error. you could also put ?? operator check for more interactive solution. 
     UObjects = new List<UObject>(); 
    } 

Và cũng cần phải ghi đè như bạn đã làm nhưng như thế này:

protected override void OnModelCreating(DbModelBuilder modelBuilder)  
    { 
     // folowwing is also necessary in case you're using identity model  
     base.OnModelCreating(modelBuilder);    
     modelBuilder.Entity<UObjects>()  
      .HasOptional<UObjects>(u => u.UParent) // EF'll load Parent if any  
      .WithMany(u => u.UObjects);  // load all childs if any 
    } 
+0

Tôi đang đạt được hành vi tương tự cho các danh mục và tiểu thể loại và nhiều nơi tự tham khảo là bắt buộc. Xin vui lòng nếu vẫn không nhận được kết quả mong muốn –

+0

Việc khởi tạo bộ sưu tập trong hàm tạo không cần thiết. EF sẽ tạo ra nó khi nó rỗng. –

1

Một lớp thực thể gần giống với lớp của bạn hoạt động trong EF Core. Tôi đã đổi tên thuộc tính của bạn ParentID thành UParentID và thêm các hàm tạo.

[Table("UObjects")] 
public class UObject 
{ 
    protected UObject() 
    { 
    UObjects = new List<UObject>(); 
    } 

    public UObject(UObject parent, string name) 
    : this() 
    { 
    Name = name; 
    UParent = parent; 
    UParent?.UObjects.Add(this); 
    } 

    [Key] 
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)] 
    public long ID { get; set; } 
    public string Name { get; set; } 
    public long? UParentID { get; set; } 

    public virtual UObject UParent { get; set; } 
    public virtual ICollection<UObject> UObjects { get; set; } 
} 

Trong ApplicationDBContext tôi chỉ có thế này:

protected override void OnModelCreating(ModelBuilder builder) 
{ 
    base.OnModelCreating(builder); 
    builder.Entity<UObject>(); 
} 

sử dụng (xem như thế nào các thuộc tính của đối tượng root được làm đầy với các giá trị đúng): Eager loading

Lưu ý: Tôi không bận tâm về việc xóa mã này. Nếu bạn cần nó, mọi thứ có thể sẽ phức tạp hơn.

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