2011-09-13 49 views
0

我有一個類文章:問題與實體框架/ DB關係

public class Article 
{ 
    public int Id { get; set; } 
    public string Text { get; set; } 
    public Title Title { get; set; } 

} 

和標題:

public class Title 
{ 
    public int Id { get; set; } 
    public string Name { get; set; } 
    public int MaxChar { get; set; } 
} 

之前,你可以寫一個Article,你要選擇你的Title從列表中,所以你的StringLength的Article.Text可以確定。意思是,這篇文章只能有一定數量的字符,取決於作者所擁有的「標題」。例如:Title.Name「標題1」只能寫一篇文章,用1000個字符(MaxChar),和Title.Name「標題2」可以寫一篇文章,3000個字符。所以。那意味着對於Article.Text的字符串長度必須來自Title.MaxChar

Title實體是將被存儲在DB前綴的數據。

這裏是香港專業教育學院宋迄今所做的: 從DB中的標題在一個視圖中列出,並鏈接到創建ArticleController的行動,「稱號」查詢字符串:

@Models.Title 

@foreach (var item in Model) { 
     @Html.ActionLink(item.Name, "Create", "Article", new { title = item.Id}, new FormMethod()) 

     } 

您填寫表格,並張貼它。 HttpPost創建操作:

[HttpPost] 
    public ActionResult Create(Article article) 
    { 
     if (article.Text.Length > article.Title.MaxChar) 
     { 
      ModelState.AddModelError("Text", 
            string.Format("The text must be less than {0} chars bla bla", article.Title.MaxChar)); 
     } 
     if (ModelState.IsValid) 
      { 
       db.Article.Add(article); 
       db.SaveChanges(); 
       return RedirectToAction("Index"); 
      } 


     return View(hb); 
    } 

這是問題所在。控制器還添加了一個新的實體。所以下次我瀏覽到必須選擇Title的視圖時,我用來寫文章的最後一個實體有一個重複。

我應該這樣做在entirly新的方式,還是有一個小的調整。只有我能想到的其他事情,只是發送MaxChar作爲查詢字符串,並且模型之間根本沒有關係。看起來有點傻/ webforms kindda。

乾杯

更新#1: 也許我這個做了錯誤的方式? 獲取創建行動

 public ActionResult Create(int title) 
    { 
     var model = new Article 
     { 
      Title = db.Title.Find(title) 
     }; 
     return View(model); 
    } 

或模型也許它?像,我必須設置外鍵嗎?喜歡的東西:

 [ForeignKey("Title")] 
    public int MaxChar { get; set; } 
    public virtual Title Title { get; set; } 

但是我敢肯定,我讀了一些在那裏,它的心不是necesary,即EF需要的照顧。

+0

聽起來像標題的Id屬性不是主鍵(或唯一)? – Rune

+0

你使用Code First嗎? – counsellorben

+0

@counsellorben代碼優先 –

回答

1

最簡單的方法很可能是附加標題上下文在Create行動:

// ... 
if (ModelState.IsValid) 
{ 
    db.Titles.Attach(article.Title); 
    db.Article.Add(article); 
    db.SaveChanges(); 
    return RedirectToAction("Index"); 
} 
// ... 

Attach告訴EF這article.Title在數據庫中已經存在,從而避免當您添加一個新的Title插入文章的上下文。

+0

無痛的解決方案。謝謝 :) –

1

您需要區分您的MVC模型和實體模型。你的MVC條模型應該是這個樣子(記住有什麼進入一個模型的一些宗教辯論):

public class Article 
{ 
    public int Id { get; set; } 
    public string Text { get; set; } 
    public int TitleID { get; set; } 
    public IEnumerable<Title> AvailableTitles {get;set;} 
} 

在您看來,您可以創建基於關閉可用標題的下拉菜單,然後綁定它到TitleID屬性。可用標題列表將填充在無參數控制器方法(以及模型綁定方法)中。

當您的模型綁定方法帶回TitleID時,將基於該ID的實體框架中的Title對象實例化。使用該Title對象創建您的Entities Article對象,並保存您的更改。這應該讓你到你想要的地方。

+0

優雅的解決方案。德夫將在未來的項目中做到這一點。但生病與Slaumas解決方案,因爲我只有我必須添加一條線,它全部工作:) –