c# - LINQ to SQL 插入失败

标签 c# asp.net-mvc linq-to-sql repository-pattern

我在尝试插入新记录时遇到了一个非常令人沮丧的问题 使用 LINQ to SQL。如果我逐步执行这段代码,有时它会插入新记录 但大多数时候它没有。当它失败时,我看到以下错误。

Cannot insert the value NULL into column 'Name', table 'EquipmentManufacturer'; column does not allow nulls. INSERT fails. The statement has been terminated.

此错误提示“名称”字段为空,但事实并非如此。当我调试并单步执行此集合时,["Name"] 具有我在表单中输入的值。

这里是建表语句。

CREATE TABLE [EquipmentManufacturer] (
  [EquipmentManufacturerID] [int] IDENTITY(1,1) NOT NULL,
  [Name] [nvarchar](50) NOT NULL,

 CONSTRAINT [PK_EquipmentManufacturer] PRIMARY KEY CLUSTERED 
 (
    [EquipmentManufacturerID] ASC
 ) ON [PRIMARY]
) ON [PRIMARY]

这是我尝试添加新记录的 ASP.NET MVC Controller 和创建操作。

public partial class EquipmentManufacturerController : Controller
{
  private IRepository<EquipmentManufacturer> reposManu;

  // POST: /EquipmentManufacturer/Create
  [AcceptVerbs(HttpVerbs.Post)]
  public virtual ActionResult Create(FormCollection collection)
  {
    EquipmentManufacturer entity = reposManu.New();
    try
    {
      //HACK: Something screwy is going on here the entity oject doesn't always get updated correctly
      //UpdateModel(entity);

      entity.Name = collection["Name"];
      reposManu.Insert(entity);
      reposManu.SubmitChanges();

      return RedirectToAction("Details", new { id = entity.EquipmentManufacturerID });
    }
    catch (RulesException ex)
    {
      ex.AddModelStateErrors(ModelState, "EquipmentManufacturer");
      return ModelState.IsValid ? RedirectToAction("Create")
        : (ActionResult)View();
    }
  }
}

这是 Create.aspx View 。

<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">

    <h2>Create</h2>

    <%= Html.ValidationSummary("Create was unsuccessful. Please correct the errors and try again.") %>

    <% using (Html.BeginForm()) {%>

        <fieldset>
            <legend>Fields</legend>
            <p>
                <label for="Name">Name:</label>
                <%= Html.TextBox("Name") %>
                <%= Html.ValidationMessage("Name") %>
            </p>
            <p>
                <input type="submit" value="Create" />
            </p>
        </fieldset>

    <% } %>
    <%= Html.ClientSideValidation<EquipmentManufacturer>() %>

    <div>
        <%=Html.ActionLink("Back to List", "Index") %>
    </div>

</asp:Content>

这是我正在使用的 Repository 实现。

public class Repository<T> : IRepository<T> where T : class
{
  public IDataContext DC { get; set; }

  public Repository(IDataContext dataContext)
  {
      DC = dataContext;
  }

  /// <summary>
  /// Return all instances of type T.
  /// </summary>
  /// <returns></returns>
  public IEnumerable<T> All()
  {
      return GetTable;
  }

  /// <summary>
  /// Return all instances of type T that match the expression exp.
  /// </summary>
  /// <param name="exp"></param>
  /// <returns></returns>
  public IQueryable<T> Find(Expression<Func<T, bool>> exp)
  {
      return GetTable.Where<T>(exp);
  }

  /// <summary>See IRepository</summary>
  /// <param name="exp"></param>
  /// <returns></returns>
  public T Single(Expression<Func<T, bool>> exp)
  {
      return GetTable.SingleOrDefault(exp);
  }

  /// <summary>See IRepository</summary>
  /// <param name="exp"></param>
  /// <returns></returns>
  public T First(Expression<Func<T, bool>> exp)
  {
      return GetTable.First(exp);
  }

  /// <summary>See IRepository</summary>
  /// <param name="entity"></param>
  public virtual void Delete(T entity)
  {
      DC.Context.GetTable<T>().DeleteOnSubmit(entity);
  }

  /// <summary>
  /// Create a new instance of type T.
  /// </summary>
  /// <returns></returns>
  public virtual T New()
  {
      T entity = Activator.CreateInstance<T>();
      GetTable.InsertOnSubmit(entity);
      return entity;
  }

  /// <summary>
  /// Adds an insance T.
  /// </summary>
  /// <returns></returns>
  public virtual void Insert(T entity)
  {
      GetTable.InsertOnSubmit(entity);
  }

  /// <summary>
  /// Update entity.
  /// </summary>
  /// <returns></returns>
  public virtual void Update(T entity)
  {
      DC.Context.Refresh(System.Data.Linq.RefreshMode.KeepCurrentValues, entity);
  }

  /// <summary>See IRepository</summary>
  public void SubmitChanges()
  {
      DC.SubmitChanges();
  }

  private string PrimaryKeyName
  {
      get { return TableMetadata.RowType.IdentityMembers[0].Name; }
  }

  private System.Data.Linq.Table<T> GetTable
  {
      get { return DC.Context.GetTable<T>(); }
  }

  private System.Data.Linq.Mapping.MetaTable TableMetadata
  {
      get { return DC.Context.Mapping.GetTable(typeof(T)); }
  }

  private System.Data.Linq.Mapping.MetaType ClassMetadata
  {
      get { return DC.Context.Mapping.GetMetaType(typeof(T)); }
  }
}

最佳答案

是因为您调用了 .InsertOnSubmit(entity) 两次吗?

你在 New() 中调用一次

public virtual T New()
{
    T entity = Activator.CreateInstance<T>();
    GetTable.InsertOnSubmit(entity);
    return entity;
}

然后再次在 .Insert() 中

public virtual void Insert(T entity)
{
    GetTable.InsertOnSubmit(entity);
}

我个人会从 New() 方法中删除 GetTable.InsertOnSubmit(entity)。

原因是我认为存储库的用户最好专门插入实体,而不是每次创建新实体时都自动设置为插入。

HTH,
查尔斯

关于c# - LINQ to SQL 插入失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1331338/

相关文章:

c# - 如何从字符串创建可读的日期和时间?

c# - MVC 绑定(bind)不适用于输入类型颜色

c# - Silverlight - 如何在 XAML 中进行国际化?

c# - 简化类道路系统的碰撞网格?

javascript - 将 ajax 响应填充到 div 中时出现问题

c# - Linq to SQL 与序列化

c# - 如何调试 linq to sql InsertOnSubmit 语句?

c# - 将实时共享托管 ASP.NET MVC 站点迁移到 Windows Azure

c# - VS 2010 一键部署问题 "Application Validation did not succeed. Unable to continue"

asp.net - 如何将我的 Autofac 容器插入 ASP。网络身份2.1