我有一个class Article:
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
,因此可以确定Article.Text
的StringLength。意思是,这篇文章只能有一定数量的字符,这取决于作者的"标题"。例如:Title.Name
"Title1"只能写1000个字符的文章(MaxChar
), Title.Name
"Title2"只能写3000个字符的文章。所以。这意味着Article.Text
的字符串长度必须来自Title.MaxChar
。
Title
实体是将存储在db中的前缀数据。
这是我目前所做的:数据库中的标题列在一个视图中,带有一个链接,用于创建带有"title"查询字符串的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
实体。下次导航到需要选择Title的视图时,会有我上次写文章时使用的实体的副本。
我应该用一种全新的方式来做这件事,还是有一个小的调整?我能想到的唯一一件事是,只是将MaxChar
作为查询字符串发送,并且模型之间没有任何关系。只是看起来有点傻/webforms kind .
UPDATE # 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; }
最简单的方法可能是在Create
动作中将标题附加到上下文:
// ...
if (ModelState.IsValid)
{
db.Titles.Attach(article.Title);
db.Article.Add(article);
db.SaveChanges();
return RedirectToAction("Index");
}
// ...
Attach
告诉EF article.Title
已经存在于数据库中,从而避免在将文章添加到上下文时插入新的Title
。
您需要区分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对象,并保存更改。