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

发布于 2024-12-04 03:32:18 字数 2280 浏览 4 评论 0原文

我有一个类文章:

    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“Title1”只能写一篇1000个字符的文章(MaxChar),而Title.Name“Title2”可以写一篇3000字的文章。所以。这意味着 Article.Text 的字符串长度必须来自 Title.MaxChar

Title 实体是将存储在数据库中的前缀数据。

这是我到目前为止所做的: 数据库中的标题列在视图中,并带有一个链接,用于使用“标题”查询字符串创建 ArticleController 的操作:

    @Models.Title

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

        }

您填写表单并发布它。 HttpPost Create 操作:

    [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 实体。因此,下次我导航到必须选择标题的视图时,会出现我用来撰写文章的最后一个实体的重复项。

我应该以全新的方式执行此操作,还是需要进行一些小调整。我唯一能想到的就是将 MaxChar 作为查询字符串发送,并且模型之间根本没有任何关系。只是看起来有点傻/网络表单有点。

干杯

更新#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; }

但我很确定我读到了一些不必要的地方,EF 会处理这个问题。

I have a class Article:

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

}

And Title:

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

Before you can write an Article, you have to choose your Title from a list, so your StringLength for Article.Text can be determined. Meaning, this article can only have a certain amount of chars, deppending on what 'Title' the writer has. Example: Title.Name "Title1" can only write an article with 1000 chars (MaxChar), and Title.Name "Title2" can write an article with 3000 chars. So. Thats means the the string length for Article.Text has to come from Title.MaxChar.

The Title entity is prefixed data that will be stored in the db.

Here's what ive done sone far:
The titles from the db are listed in a view, with a link to create action of the ArticleController with a "title" querystring:

    @Models.Title

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

        }

You fill the form, and post it. The HttpPost Create action:

    [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);
    }

Here's the issue. The controller also adds a new Title entity. So the next time I navigate to the view where I have to choose Title, there's a duplicate of the last entity I used to write an article.

Should I do this in an entirly new way, or is there a small tweak. Only other thing I can think of, is just sending the MaxChar as a querystring, and have no relations between the models at all. Just seems a bit silly/webforms kindda.

Cheers

UPDATE #1:
Maybe im doing this the wrong way?
Get Create action

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

Or maybe its in the Model? Like, do I have to set foreign keys? Something like:

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

But im pretty sure I read some where that it isnt necesary, that EF takes care of that.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

凉薄对峙 2024-12-11 03:32:18

最简单的方法可能是将标题附加到 Create 操作中的上下文:

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

Attach 告诉 EF article.Title 已存在于数据库中,从而避免在将文章添加到上下文时插入新的 Title

Easiest way would probably be to attach the title to the context in your Create action:

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

Attach tells EF that article.Title already exists in the database, thereby avoiding that a new Title is inserted when you add the article to the context.

爱人如己 2024-12-11 03:32:18

您需要区分 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 对象,并保存更改。这应该能让你到达你想去的地方。

You need to have a distinction between your MVC model and your Entities model. Your MVC Article model should look something like this (bear in mind there are some religious debates about what goes into a model):

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

In your view, you can create a dropdown based off the available titles, and bind it to the TitleID property. The list of available titles would be populated in the parameterless controller method (and the model-bound method as well).

When your model-bound method brings back the TitleID, instantiate the Title object from the Entities framework based off the ID. Create your Entities Article object using that Title object, and save your changes. This should get you where you want to be.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文