微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何将来自不同实体的项目动态添加到ASP.NET Core MVC中的列表

如何解决如何将来自不同实体的项目动态添加到ASP.NET Core MVC中的列表

这是我第一次使用列表,这是我的第一次经历,我遇到的情况很复杂。我想添加一个类型为 Story 的对象,该对象具有可以动态添加句子列表。句子与图像具有一对一的关系,与音频具有一对一的关系(可以选择添加)。我设法将句子列表和故事对象一起添加数据库中。但是我不知道从其他两个实体开始。

以下是每个实体的模型:

public class Story
{
    public int StoryId { get; set; }
    public string Title { get; set; }
    public string Type { get; set; }
    public DateTime Date { get; set; }

    public virtual IEnumerable<Sentence> Sentences { get; set; } // one to many Story-Sentence
}

句子类:

public class Sentence
{
    public int Id { get; set; }
    public string SentenceText { get; set; }

    public virtual Audio Audio { get; set; } // one to one Sentence-Audio
    public virtual Image Image { get; set; } // one to one Sentence-Image
}

图片类:

public class Image
{
    [Key]
    [ForeignKey("Sentence")]
    public int Id { get; set; }
    public string ImageSelected { get; set; }
    public virtual Sentence Sentence { get; set; }
}

Audio类与Image类完全一样。视图。

@model Story
<div id="editorRows">
    @foreach (var item in Model.Sentences)
    {
        <partial name="_SentenceEditor" model="item" />
    }
</div>
<a id="addItem" asp-action="BlankSentence" asp-controller="StoryTest">Add Sentence...</a> <br />
<input type="submit" value="Finished" />

局部视图

@model Sentence
<div class="editorRow">
    @using (Html.BeginCollectionItem("sentences"))
    {
        <span>Name: </span> @Html.EditorFor(m => m.SentenceText);
    }
    @using (Html.BeginCollectionItem("sentences"))
    {
        <span>Image: </span> @Html.EditorFor(m => m.Image.ImageSelected);
    }
    <a href="#" class="deleteRow">delete</a>
</div>

还有一些可以动态添加删除行的JavaScript。

最后在Controller中,我只是将模型保存在数据库

        [HttpPost]
    public async Task<IActionResult> AddTwo(Story model/*IEnumerable<Sentence> sentence*/)
    {
        if (ModelState.IsValid)
        {
            _db.Story.Add(model);
            await _db.SaveChangesAsync();
            return RedirectToAction("Index");
        }
        return View(model);
    }

简而言之,我想在句子中添加图片和音频。并且能够正确访问整行进行编辑。

解决方法

您有几种选择

选项1将为所有子对象提供一个表,该表具有所有类型的对象的所有字段。有些可能是所有对象共有的,例如标题,其他将适用于一种对象。您需要一个名为ObjectTypeId之类的字段-您可以将此字段链接到具有每种类型的文本名称的表。您还可以为此ID创建一个枚举,以允许您使用C#switch和case语句来决定如何显示对象,保存值等。

选项2将在不同的表中具有不同的对象。然后,您的句子具有多个可为空的字段,这些字段可链接到每种类型的对象表,其中只有一个具有整数-其余的为null(除非您以某种方式希望在同一句子中包含多个对象)。您可以再次使用ObjectTypeId或依靠链接到不为null的子代的列之一。与选项1一样,由于某些原因,您可能希望使用一个空句子-要考虑的事情

,

我根据您的代码进行了演示。您可以将数据存储在formData中,然后使用ajax将其传递给控制器​​操作。

主视图:

@model Story
<form asp-action="AddSentence" method="post">
    <div id="editorRows">
        <input type="hidden" name="" value="@Model.StoryId" />
        @foreach (var item in Model.Sentences)
        {
            <partial name="_SentenceEditor" model="item" />
        }
    </div>
    <a id="addItem" asp-action="BlankSentence" asp-controller="StoryTest">Add Sentence...</a>
    <br />
    <input type="submit" id="submit" value="Finished" />
</form>

@section scripts {
    <script>
        $("#submit").click(function (e) {
            e.preventDefault();
            var formData = new FormData();

            $("input[name='Audio.AudioSelected']").each(function (i) {
                var AudioSelected = $(this).val();
                formData.append("Sentences[" + i + "].Audio.AudioSelected",AudioSelected);

            });
            $("input[name='Image.ImageSelected']").each(function (i) {
                var ImageSelected = $(this).val();
                formData.append("Sentences[" + i + "].Image.ImageSelected",ImageSelected);

            });
            $("input[name='SentenceText']").each(function (i) {
                var SentenceText = $(this).val();
                formData.append("Sentences[" + i + "].SentenceText",SentenceText);

            });

            $.ajax({
                method: 'post',url: "StoryTest/AddSentence",data: formData,processData: false,contentType: false,success: function () {

                }
            });

        });

        $("#addItem").click(function () {
            $.ajax({
                url: this.href,cache: false,success: function (html) { $("#editorRows").append(html); }
            });
            return false;
        });

        $("a.deleteRow").on("click",function () {
            $(this).parents("div.editorRow:first").remove();
            return false;
        });
    </script>
}

部分视图:

@model Sentence
<div class="editorRow">

    <span>Name: </span> @Html.EditorFor(m => m.SentenceText)

    <span>Audio: </span> @Html.EditorFor(m => m.Audio.AudioSelected)

    <span>Image: </span> @Html.EditorFor(m => m.Image.ImageSelected)

    <a href="#" class="deleteRow">delete</a>
</div>

控制器:

public IActionResult Index()
{
    Story story = new Story
    {
        Sentences = new List<Sentence>
        {
            new Sentence { Id = 1,SentenceText = "AAA",Audio = new Audio{ AudioSelected = "True"},Image = new Image{ ImageSelected = "True"} },new Sentence { Id = 2,SentenceText = "BBB",Audio = new Audio{ AudioSelected = "False"},Image = new Image{ ImageSelected = "False"}},new Sentence { Id = 3,SentenceText = "CCC",Image = new Image{ ImageSelected = "False"}}
        }
    };
    return View(story);
}

[HttpPost]
public async Task<IActionResult> AddSentence(Story model)
{
    if (ModelState.IsValid)
    {
        _db.Story.Add(model);
        await _db.SaveChangesAsync();
        return RedirectToAction("Index");
    }
    return View(model);
}

public IActionResult BlankSentence()
{
    return PartialView("_SentenceEditor",new Sentence());
}

结果:

enter image description here

,

选项3-我有时会用到它,但是它确实使业务模型与数据库断开了连接-但出于完整性考虑,我将其包括在内。

您有一个简单的记录,其中包含多种类型。您只需添加一个额外字段,其中包含不同类型的数据。我将其设为varchar(MAX),并将其命名为JsonData。

然后要做的是基于数据库类创建部分模型,并添加所有属性以获取和设置所需的类型。这些是简单的一线客。

您还可以具有更复杂的实例,例如可能是列表列表,这不会增加数据库上下文代码的复杂性。

与数据库上下文类版本相比,您的视图模型和视图并没有真正改变。如果您使用的是SQL Server,还可以将JSON转换为可包含在查询中的列

/// <summary>
/// Gets or sets card instance from JSON data for resource. Null if not a card
/// </summary>
public Card CardGet
{
    get
    {
        if (this.ResourceTypeEnum == ResourceTypeEnumeration.Card)
        {
            return JsonSerializer.Deserialize<Card>(this.JsonData);
        }

        // not a card
        return null;
    }

    set
    {
        this.JsonData = JsonSerializer.Serialize(value);
    }
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。