我在尝试插入新记录时遇到了一个非常令人沮丧的问题 使用LINQ to SQL。如果我单步执行此代码,它会插入新记录 但大多数时候它没有。当它失败时,我看到以下错误。
无法将值NULL插入 列'名称',表格 'EquipmentManufacturer';专栏 不允许空值。 INSERT失败。该 声明已被终止。
这个错误抱怨'Name'字段为null但不应该是这种情况。当我调试并逐步执行此集合时,[“名称”]具有我在表单上输入的值。
这是表create语句。
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控制器和创建操作。
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视图。
<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)); }
}
}
答案 0 :(得分:3)
是因为你要两次调用.InsertOnSubmit(实体)吗?
您在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(实体)。
原因是我认为存储库的用户更好地专门插入实体,而不是每次创建新实体时都自动设置插入实体。
HTHS,
查尔斯
答案 1 :(得分:1)
我遇到了这个问题,因为我已将* .dbml Ling2SQL文件中的Auto Generated Value
选项设置为true
;我将其更改为false
,错误消失了。这是一个简单的错误,但由于我没有故意将值设置为true
,因此我花了很长时间才找到它。
答案 2 :(得分:0)
根据我的经验,这类问题通常来自映射配置中的错误。
寻找答案的一些建议:
使用SQL事件探查器跟踪INSERT语句,这可能会为您提供更多线索。
仔细检查EquipmentManufacturer类的映射,可能无法正确映射名称。在您的问题中包含该信息,因为它可以更好地了解问题。
答案 3 :(得分:0)
我看到你没有使用'自动绑定'(或者你所谓的任何你接受你想要绑定的实体作为动作方法参数),而是(A)新建对象和(B)手动设置formCollection的“Name”属性。也许我看不出“EquipmentManufacturerID”被绑定在哪里了?
此EquipmentManufacturerID属性上的NULL失败了吗?