2015-06-25 5 views
1

Я использую Entity Framework и JQuery для обновления значений в столбце таблицы SQL с битным типом данных. Это делается путем считывания значений в таблицу html, а затем с помощью кнопки, которая изменит значение бита для каждой строки.Ошибка базы данных базы данных - Entity Framework

Здесь вы можете увидеть 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(); 
    } 

Категория объекта для r правочник:

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

} 

}

Выход из Diagnostics отладки:

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 изменяется для инвалидов (0), но значение бита в базе данных не изменяется. Я должен что-то упустить. Спасибо за вашу помощь!

+0

Вы говорите бит, но перечисления обычно отображаются в целые числа. Можете ли вы отправить сопоставление? Кроме того, как вы создали БД? Попробуйте изменить бит на целое число – bubi

+0

Db уже создан. Я просто добавил столбец состояния в существующую таблицу. Я попытаюсь изменить бит на int. Если бы я захотел сохранить его, я бы изменил перечисление? – cfly24

+2

Добавьте следующий код после строки, в которой вы добавили 'CategoryDBEntities':' connection.Database.Log = s => Debug.WriteLine (s); '. Это выведет SQL, который генерирует EF, когда вы вызываете 'SaveChanges()'. Что ты видишь? – sstan

ответ

0

Я сделаю это ответом, потому что я уверен, что если вы нанесете действие методу действия, вам нужно будет сделать это, прежде чем сохранять изменения.

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

Это позволяет EF выпускать обновление по пройденной записи. Я по-прежнему думаю, что вы можете столкнуться с проблемами, не имеющими состояние, которое является логическим и пытается сохранить бит.

Юмор нам и попробовать следующее:

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

И

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

Я делаю предположение, вы используете код первой, чтобы создать свою базу данных, но независимо от того, я точно знаю, что, если вы генерировать из существующей БД, поле будет bool, если оно немного в db. Что-то еще, чтобы рассмотреть это, возможно, должен быть столбцом с нулевым значением в БД, если вы не задали значение по умолчанию каким-то образом. Просто замените:

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

Это хороший тест, чтобы попробовать. Но это не правильное решение, потому что объект уже является частью контекста. Изменение свойства должно быть достаточным. Установка сущности «Модифицированная» требуется, если вы прикрепляете отключенный объект. – sstan

+0

Я все еще склоняюсь к тому, чтобы бит неправильно отображался. EF в моем опыте всегда рассматривал битовые поля как логические в коде. – Shawn

+0

Я пробовал это, и он по-прежнему не изменился в базе данных:/ – cfly24

0

Не похоже, что вы фактически передаете измененный элемент обратно в базу данных. Вы только изменяете копию, которую вы сделали из нее.

Чтобы гарантировать, что данные изменены в БД, вы хотите сделать что-то вроде следующего:

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

Это хороший тест, чтобы попробовать. Но это не правильное решение, потому что объект уже является частью контекста. Изменение свойства должно быть достаточным. Установка сущности «Модифицированная» требуется, если вы прикрепляете отключенный объект. – sstan

+0

Хммм ... это еще не решило проблему. Не слишком уверен, что еще может произойти – cfly24

2

Ваш state столбец не отображается на всех между EF и базой данных.

Вы можете увидеть это в журнале SQL:

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


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

Обратите внимание, что state столбец не выбран вообще.

Посмотрите, есть ли значение свойства state, которое необходимо игнорировать с помощью аннотации [NotMapped] или в свободной конфигурации API, например entityTypeConfiguration.Ignore(p => p.state).

Как только у вас есть это исправление, я ожидаю, что вы получите исключения из-за того, что вы переписываете перечисление в поле бит. Как утверждают другие, вы, вероятно, захотите использовать логическое для своей собственности.

0

Наконец-то выяснилось! Спасибо @Shawn за помощь!

На самом деле произошло несколько вещей.

Во-первых, как вы предложили мне пришлось изменить StatesType перечисление в BOOL так отображались бы правильно:

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

С его Теперь BOOL я установить состояние ложь:

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 и нажать «Обновить модель из базы данных», а затем обновить таблицу.

Спасибо за помощь!

Смежные вопросы