2011-09-13 46 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解决方案,因为我只有我必须添加一条线,它全部工作:) –