数据库未更新错误 - 实体框架

时间:2015-06-25 17:45:01

标签: javascript c# jquery asp.net-mvc entity-framework

我正在使用Entity Framework和JQuery来更新具有位数据类型的SQL表列中的值。这是通过将值读入html表,然后使用一个按钮来改变每行的位值来完成的。

在这里你可以看到html表:

    <table id="categoryList" class="table">
    <thead>
    <tr>
        <th>Category ID</th>
        <th>Category Name</th>
    </tr>
    </thead>
    <tbody>
    @foreach (var item in Model.Categories)
    {
        <tr>
            <td>@item.id</td>
            <td>@item.name</td>
            <td>
                <button class="btn btn-success categoryEnabled" data-id="@item.id">Enabled</button>
            </td>
        </tr>
    }
    </tbody>
</table>

然后,这是我用来启动点击操作的脚本:

$(".categoryEnabled").on("click", function() {
    $(this).hide();
    $(this).next().show();
    if (!e) var e = window.event;
    e.cancelBubble = true;
    if (e.stopPropagation) {
        e.stopPropagation();
    }
    DisableRow($(this).data('id'));
});

function DisableRow(id) {
    $.post('@Url.Action("DisableRow", "Category")', { "Id": id }, function () {
        alert('Row Disabled!');
    }).fail(function () {
        alert('Error disabling row!');
    });
}

然后将其链接到控制器操作,该操作应更改所选行的状态位值并更新:

public void DisableRow(int id)
    {
        var connection = new CategoryDBEntities();

        var record = connection.Categories.Find(id);

        if (record == null) return;

        record.state = StatesTypes.Disabled;

        connection.SaveChanges();
    }

此类别对象供参考:

namespace Project.Models
{
using System;
using System.Collections.Generic;

    public enum StatesTypes
    {
        Disabled = 0,
        Enabled = 1
    }

public partial class Category
{

    public int id { get; set; }
    public string name { get; set; }
    public StatesTypes state { get; set; }
}

}

的DbContext:

namespace Project.Models
{
using System;
using System.Data.Entity;
using System.Data.Entity.Infrastructure;

public partial class CategoryDBEntities : DbContext
{
    public QualityDBEntities()
        : base("name=CategoryDBEntities")
    {
    }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        throw new UnintentionalCodeFirstException();
    }

    public DbSet<Category> Categories { get; set; }

}

}

诊断调试的输出:

SELECT TOP (2) 
[Extent1].[id] AS [id], 
[Extent1].[name] AS [name]
FROM [dbo].[Category] AS [Extent1]
WHERE [Extent1].[id] = @p0


-- p0: '5' (Type = Int32)

问题是record.state更改为disabled(0),但数据库中的位值不会更改。我必须在这里遗漏一些东西。谢谢你的帮助!

4 个答案:

答案 0 :(得分:2)

Your state column is not being mapped at all between EF and your database. You can see this in your SQL log: SELECT TOP (2) [Extent1].[id] AS [id], [Extent1].[name] AS [name] FROM [dbo].[Category] AS [Extent1] WHERE [Extent1].[id] = @p0 -- p0: '5' (Type = Int32) Notice that the state column is not being selected at all. Look to see if you have configured the state property to be ignored by using an annotation [NotMapped], or fluent API configuration like entityTypeConfiguration.Ignore(p => p.state). Once you have that fixed, I expect you'll be getting exceptions about the fact that you're mapping an enum to a bit field. As others are suggesting, you probably want to use a boolean for your property.

答案 1 :(得分:0)

I will make this an answer because I am pretty sure if you are hitting the action method at some point you will need to do this before saving changes.

connection.Entry(record).State = EntityState.Modified;
connection.SaveChanges();    

This allows EF to issue an update on the record passed. I still think you might run into issues not having the state be a boolean and trying to save to a bit field though.

Humor us and try the following:

public void DisableRow(int id)
{
    var connection = new CategoryDBEntities();

    var record = connection.Categories.Find(id);

    if (record == null) return;

    record.state = false; //Assume false for disabled

    connection.SaveChanges();
}

And

public partial class Category
{
    public int id { get; set; }
    public string name { get; set; }
    public bool state { get; set; }
}

I am making the assumption you are using code first to create your database, but regardless I know for a fact if you generate from an existing DB the field will be a bool if it is a bit in the db. Something else to consider it might need to be a nullable column on the DB unless you set a default some how. Simply replace:

public bool state { get; set; }
//with
public bool? state { get; set; }

答案 2 :(得分:0)

It doesn't look like you're actually committing the changed item back to the database. You're only altering the copy you've made of it.

To ensure that the data is altered in the DB you want to do something like the following:

connection.Categories.Attach(record);
connection.Entry(record).State = System.Data.Entity.EntityState.Modified;
connection.SaveChanges();

答案 3 :(得分:0)

终于搞清楚了!谢谢@Shawn的所有帮助!

实际上有几件事正在发生。

首先,就像你建议我必须将StatesType枚举更改为bool,以便正确映射:

public partial class Category
{
public int id { get; set; }
public string name { get; set; }
public bool state { get; set; }
}

由于现在bool我将状态设置为false:

public void DisableRow(int id)
{
var connection = new CategoryDBEntities();

var record = connection.Categories.Find(id);

if (record == null) return;

record.state = false;

connection.SaveChanges();
}

这里的一个大问题以及它没有在数据库中显示任何变化的主要原因是因为状态列没有在EF和数据库之间进行映射(在其中一个答案中也引用了它)。

这是因为状态列是在SQL Server Management中创建的;不是VS.所以我不得不进入.edmx并点击“从数据库更新模型”。然后刷新表。

感谢您对此提供的所有帮助!