实体框架/数据库关系的问题



我有一个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对象,并保存更改。

相关内容

  • 没有找到相关文章

最新更新