C# LINQ到SQL插入失败
我在尝试插入新记录时遇到了一个非常令人沮丧的问题 使用LINQ到SQL。如果我单步执行此代码,它有时会插入新记录 但大多数情况下,情况并非如此。当它失败时,我看到以下错误 无法将值NULL插入到 列“名称”,表 “设备制造商”;专栏是这样的 不允许空值。插入失败。这个 声明已终止 此错误抱怨“Name”字段为空,但情况不应如此。当我调试并单步执行此集合时,[“Name”]具有我在表单上输入的值 下面是tablecreate语句C# LINQ到SQL插入失败,c#,asp.net-mvc,linq-to-sql,repository-pattern,C#,Asp.net Mvc,Linq To Sql,Repository Pattern,我在尝试插入新记录时遇到了一个非常令人沮丧的问题 使用LINQ到SQL。如果我单步执行此代码,它有时会插入新记录 但大多数情况下,情况并非如此。当它失败时,我看到以下错误 无法将值NULL插入到 列“名称”,表 “设备制造商”;专栏是这样的 不允许空值。插入失败。这个 声明已终止 此错误抱怨“Name”字段为空,但情况不应如此。当我调试并单步执行此集合时,[“Name”]具有我在表单上输入的值 下面是tablecreate语句 CREATE TABLE [EquipmentManufacture
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();
}
}
}
公共部分类设备制造商控制器:控制器
{
私人电子逆向报告;
//POST:/设备制造商/创建
[接受动词(HttpVerbs.Post)]
公共虚拟操作结果创建(FormCollection集合)
{
设备制造商实体=reposManu.New();
尝试
{
//哈克:这里发生了一些奇怪的事情实体项目并不总是得到正确更新
//更新模型(实体);
entity.Name=集合[“Name”];
reposManu.插入(实体);
reposManu.SubmitChanges();
返回RedirectToAction(“Details”,new{id=entity.EquipmentManufacturerID});
}
捕获(规则例外)
{
例如AddModelState错误(ModelState,“设备制造商”);
return ModelState.IsValid?重定向到操作(“创建”)
:(ActionResult)视图();
}
}
}
下面是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>
创造
领域
姓名:
下面是我正在使用的存储库实现
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)); }
}
}
公共类存储库:IRepository,其中T:class
{
公共IDataContext DC{get;set;}
公共存储库(IDataContext dataContext)
{
DC=数据上下文;
}
///
///返回T类型的所有实例。
///
///
公共IEnumerable All()
{
返回GetTable;
}
///
///返回与表达式exp匹配的T类型的所有实例。
///
///
///
公共IQueryable查找(表达式exp)
{
返回GetTable.Where(exp);
}
///见E假设
///
///
公共T单(表达式exp)
{
返回GetTable.SingleOrDefault(exp);
}
///见E假设
///
///
公共T优先(表达式exp)
{
返回GetTable.First(exp);
}
///见E假设
///
公共虚拟作废删除(T实体)
{
DC.Context.GetTable().DeleteOnSubmit(实体);
}
///
///创建类型为T的新实例。
///
///
公共虚拟T New()
{
T entity=Activator.CreateInstance();
GetTable.InsertOnSubmit(实体);
返回实体;
}
///
///增加了一个疯狂的T。
///
///
公共虚拟无效插入(T实体)
{
GetTable.InsertOnSubmit(实体);
}
///
///更新实体。
///
///
公共虚拟无效更新(T实体)
{
DC.Context.Refresh(System.Data.Linq.RefreshMode.KeepCurrentValues,实体);
}
///见E假设
公开作废提交更改()
{
DC.提交更改();
}
私有字符串PrimaryKeyName
{
获取{return TableMetadata.RowType.IdentityMembers[0].Name;}
}
private System.Data.Linq.Table可获取
{
获取{return DC.Context.GetTable();}
}
private System.Data.Linq.Mapping.MetaTable表元数据
{
get{return DC.Context.Mapping.GetTable(typeof(T));}
}
private System.Data.Linq.Mapping.MetaType类元数据
{
get{return DC.Context.Mapping.GetMetaType(typeof(T));}
}
}
根据我的经验,这类问题通常来自映射配置中的错误
找到答案的一些建议:
- 使用SQL探查器跟踪INSERT语句,这可能会为您提供更多线索
- 仔细检查EquipmentManufacturer类的映射,名称可能映射不正确。在你的问题中包含这些信息,因为它可以更好地描述问题
此EquipmentManufacturerID属性是否为空失败?是否因为您调用了.InsertOnSubmit(实体)两次 你称它为纽约一次() 就我个人而言,我会从New()方法中删除GetTable.InsertOnSubmit(entity) 原因是,我认为存储库的用户最好专门插入实体,而不是在每次创建新实体时自动设置插入 HTHs,
Charles我遇到了这个问题,因为我在*.dbml Ling2SQL文件中将
自动生成的值
选项设置为true
;我将其更改为false
,错误消失了。这是一个简单的错误,但我花了很长时间才发现,因为我没有故意将Name属性的值设置为true
No。我尝试过使用诸如public virtual ActionResult Create([Bind()]EquipmentManufacturer)之类的方法签名,但仍然存在相同的问题。您是否尝试过记录LTS生成的底层SQL?如果您能看到它向服务器发送了什么,它可能会帮助您进一步调试…?我使用了SQL Profiler,我看到传入的Name参数为null。我不知道发生了什么,因为在这一行reposManu.Insert(entity)entity.Name不是null.Trace-through
public virtual T New()
{
T entity = Activator.CreateInstance<T>();
GetTable.InsertOnSubmit(entity);
return entity;
}
public virtual void Insert(T entity)
{
GetTable.InsertOnSubmit(entity);
}