2011-03-06 58 views
0

我有我需要建模以下業務角色:繼承和許多一對多的關係

  • 投標人可以,只要他們已經與這個人

  • 互動率賣家

    競拍者只有在贏得拍賣時才能評價物品

  • 儘管賣家的最終評價是從物品評價和其他人的評價中取得的平均值。

  • 評分本身(無論是項目還是用戶)是幾個問題得分的平均值。

因此,我認爲我應該創建一個Ratings類,然後用UserRating和ItemRating繼承它。這兩個應該有一個評級問題的ICollection(這將最終是一個靜態表)。 UserRating的問題與ItemRating的問題不同,但我認爲爲這些問題創建單獨的表/實體並不值得(或者我應該做一個TPH繼承?)。

所以,在這裏就是我有這麼遠:

public abstract class Rating 
{ 
    public int Id { get; set; } 

    public virtual User By { get; set; } 
} 

public class UserRating : Rating 
{ 
    public virtual User For { get; set; } 

    public virtual ICollection<RatingQuestion> Questions { get; set; } 
} 


public class ItemRating : Rating 
{ 
    public virtual Item For { get; set; } 

    public virtual ICollection<RatingQuestion> Questions { get; set; } 
} 


public class RatingQuestion 
{ 
    public int Id { get; set; } 

    public string Text { get; set; } 

    public virtual ICollection<Rating> Rating { get; set; } 
} 

爲什麼我把ICollection的子類中,而不是評級基類的原因是因爲兩者的RatingQuestion是不同的,但我我不確定這是我應該怎麼做的,如果我錯了,請糾正我。

我需要一些幫助的一件事是決定是否去TPH或TPT繼承。我想保持簡單,但我也想保持我的數據庫正常化。而且,績效是一個需要考慮的因素。

現在,我需要知道如何做的最後一件事是:如何映射評級類(基類或子類,不知道應該使用哪一個)之間的多對多關係,和使用Fluent API的RatingQuestion類,並添加屬性(分數),這是屬性關係本身,因此我可以在每個單獨的RatingQuestion上記錄分數。

我希望這已經夠清楚了。所有建議都非常受歡迎。提前致謝!

UPDATE:(拉吉斯拉夫Mrnka的答案後)

public abstract class Rating 
{ 
    public int Id { get; set; } 
    public virtual User By { get; set; } 
    public virtual ICollection<RatingQuestion> RatingQuestions { get; set; } 
} 

public class UserRating : Rating 
{ 
    public virtual User For { get; set; } 
    public virtual ICollection<Question> Questions { get; set; } 
} 

public class ItemRating : Rating 
{ 
    public virtual Item For { get; set; } 
    public virtual ICollection<Question> Questions { get; set; } 
} 

public class User 
{ 
    public int Id { get; set; } 
    //more properties 
    public virtual ICollection<UserRating> OwnRatings { get; set; } 
    public virtual ICollection<UserRating> RatingsForOthers { get; set; } 
    public virtual ICollection<ItemRating> ItemRatings { get; set; } 
} 

public class Item 
{ 
    public int Id { get; set; } 
    //more properties 
    public virtual ItemRating Rating { get; set; } //because an Item will have only one rating 
} 

public class UserRatingConfiguration : EntityTypeConfiguration<UserRating> 
{ 
    public UserRatingConfiguration() 
    { 
     HasOptional(p => p.By) 
      .WithMany(u => u.RatingsForOthers) 
      .IsIndependent() 
      .Map(m => m.MapKey(c => c.Id, "RatingSubmitter")); 

     HasRequired(p => p.For) 
      .WithMany(u => u.OwnRatings) 
      .IsIndependent() 
      .Map(m=>m.MapKey(c => c.Id, "RatedSeller")); 
    } 
} 

public class ItemRatingConfiguration : EntityTypeConfiguration<ItemRating> 
{ 
    public ItemRatingConfiguration() 
    { 
     HasRequired(p => p.By) 
      .WithMany(u => u.ItemRatings) 
      .IsIndependent() 
      .Map(m=>m.MapKey(c => c.Id, "ItemRatingSubmitter")); 
    } 
} 

我得到在SQL Server中,這顯然是被我搞砸映射造成了非常搞砸模型。任何建議,或者我應該只是遺忘了繼承和DRY原則在一起的情況?

回答

1

如果您需要將自定義屬性添加到該關係,則不能使用直接M:N映射。在這種情況下,您需要將交接表建模爲另一個實體,該實體將參照RatingQuestion並且還包括Score屬性。

我會推薦使用TPH繼承。它使用起來更容易,性能更好。 TPT的構造確實是ugly queries。也沒有理由在派生類中有RatingQuestions。這兩個集合都引用相同的類型,因此您可以將其移至父級。此外,根據this question,在使用TPH時,子類中的導航屬性存在一些問題。我不確定這個問題在Code-first中是否仍然有效。無論如何,你現在的模型根本不需要孩子的導航屬性。

如果你按照我的建議,你不需要添加任何映射。在使用這些類時,它將使用默認約定進行映射:

public abstract class Rating 
{ 
    public virtual int Id { get; set; } 
    public virtual User By { get; set; } 

    private ICollection<RatingQuestion> _ratingQuestions = null; 
    public ICollection<RatingQuestion> RatingQuestions 
    { 
     get 
     { 
      if (_ratingQuestions == null) 
      { 
       _ratingQuestions = new HashSet<RatingQuestion>(); 
      } 
      return _ratingQuestions; 
     } 
     protected set { _ratingQuestions = value; } 
    } 
} 

public class ItemRating : Rating 
{ 
    public virtual Item For { get; set; } 
} 

public class UserRating : Rating 
{ 
    public virtual User For { get; set; } 
} 

public class RatingQuestion 
{ 
    public virtual int Id { get; set; } 
    public virtual int Score { get; set; } 
    public virtual Rating Rating { get; set; } 
    public virtual Question Question { get; set; } 
} 

public class Question 
{ 
    public virtual int Id { get; set; } 
    public virtual string Text { get; set; } 

    private ICollection<RatingQuestion> _ratingQuestions = null; 
    public ICollection<RatingQuestion> RatingQuestions 
    { 
     get 
     { 
      if (_ratingQuestions == null) 
      { 
       _ratingQuestions = new HashSet<RatingQuestion>(); 
      } 
      return _ratingQuestions; 
     } 
     protected set { _ratingQuestions = value; } 
    } 
} 
+0

這雖然有些幫助,但我仍然遇到了映射問題。我需要使用Fluent API來將事情組織在生成的數據庫中。我會更新我的初始文章,以便您瞭解我們現在處理的內容。 – Kassem 2011-03-06 16:39:07

+0

@Kassem:如果您在評分中有By字段,則不能有兩個單獨的集合 - 一個用於UserRating和一個用於ItemRating。評級只能有一個。另外我不明白爲什麼衍生評級仍然有問題的集合。 – 2011-03-06 20:43:54

+0

哦,我的壞,我忘了從派生類中刪除ICollection,現在修復。你能編輯你的文章並告訴我怎樣才能解決By字段問題嗎?非常感謝! – Kassem 2011-03-06 21:18:03