2013-05-07 116 views
2

我试图将用户首选项保存到表中,但得到一个空异常,我不明白为什么。这是一个MVC 4应用程序,这是我得到错误的行为结果。不能将值NULL插入列错误

public ActionResult Go(string path, string name) 
    { 
     RaterContext r = new RaterContext(); 
     UserData u = new UserData(); 

     var userid = u.GetCurrentUserData().UserId; 
     var info = r.RatersInfo.Where(w => w.RaterName.Equals(name)).FirstOrDefault(); 
     var pref = r.RatersPreferences.Where(w => w.RaterId.Equals(info.RaterId) && w.UserId.Equals(userid)).FirstOrDefault(); 

     if (pref != null && pref.Count > 0) 
     { 
      pref.Count++; 

      r.SaveChanges(); 
     } 
     else 
     { 
      pref = new RaterPreferences(); 

      pref.UserId = userid; 
      pref.RaterId = info.RaterId; 
      pref.Count = 1; 

      r.RatersPreferences.Add(pref); 
      r.SaveChanges(); 
     } 

     return Redirect(path); 
    } 

没有什么保存在首选项表还因此被击中else块和r.SaveChanges抛出一个空异常();.唯一的例外是

无法将NULL值插入列“用户ID”,表 “WebSiteNew.dbo.RaterPreferences”;列不允许有空值。 INSERT 失败。\ r \ n声明已终止。

这是没有道理的原因是因为所有三个属性,包括UserId都有数据,当我通过。这些是表格中唯一的字段。 UserId = 1,RaterId = 6且Count清楚地设置为1.它们都被设置为不可为空的整数,并且主键是UserId和RaterId的组合。我的模型如下。

public class RaterContext : DbContext 
{ 
    public RaterContext() 
     : base("DefaultConnection") 
    { 
    } 

    public DbSet<RaterInfo> RatersInfo { get; set; } 
    public DbSet<RaterPreferences> RatersPreferences { get; set; } 
} 

[Table("RaterInfo")] 
public class RaterInfo 
{ 
    [Key] 
    [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)] 
    public int RaterId { get; set; } 
    public string RaterName { get; set; } 
    public string RaterLink { get; set; } 
    public string Section { get; set; } 
    public string Department { get; set; } 
} 

[Table("RaterPreferences")] 
public class RaterPreferences 
{ 
    [Key] 
    [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)] 
    public int UserId { get; set; } 
    public int RaterId { get; set; } 
    public int Count { get; set; } 
} 

任何帮助将不胜感激,因为我是相对较新的MVC和ASP.NET。如果您需要更多信息,请与我们联系。提前致谢!

我不知道这是否有帮助,但我测试通过手动添加数据来查看UPDATE上会发生什么,因此它会捕获if块并且工作正常。我只在INSERT上发生错误。

以下是相关表格的create语句。

SET ANSI_NULLS ON 
GO 

SET QUOTED_IDENTIFIER ON 
GO 

CREATE TABLE [dbo].[RaterPreferences](
[UserId] [int] NOT NULL, 
[RaterId] [int] NOT NULL, 
[Count] [int] NOT NULL, 
PRIMARY KEY CLUSTERED 
(
[UserId] ASC, 
[RaterId] ASC 
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF,  ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] 
) ON [PRIMARY] 

GO 

ALTER TABLE [dbo].[RaterPreferences] WITH CHECK ADD CONSTRAINT  [FK_RaterPreferences_RaterInfo] FOREIGN KEY([RaterId]) 
REFERENCES [dbo].[RaterInfo] ([RaterId]) 
GO 

ALTER TABLE [dbo].[RaterPreferences] CHECK CONSTRAINT [FK_RaterPreferences_RaterInfo] 
GO 

回答

0

我抄你的代码到一个全新的ASP.Net MVC项目与实体框架的当前版本,我可以没有任何问题运行代码。我逃跑时代码的UserData收购,看起来像:

 RaterContext r = new RaterContext(); 
     //UserData u = new UserData(); 

     var userid = 1; // u.GetCurrentUserData().UserId; 
     var info = r.RatersInfo.Where(w => w.RaterName.Equals(name)).FirstOrDefault(); 

,并没有运行该代码的其余部分的问题。

我想你的RaterPreferences表的键和数据库结构可能存在一些问题。我不知道你的完整的数据模型,但我不明白这是如何适用的,它不像你描述的那样在代码中键入。

编辑: 我修改了我的数据库表以反映您描述的设计。你的EntityFramework代码优先实现和你的数据库有区别。它看起来像你的数据库首先存在,我会删除你的EntityFramework类,并用数据库优先技术重建它们。

+1

您已使用“Key”属性在RaterPreferences类上修饰了UserID属性,该属性将UserID设置为RaterPreferences表的主键中的唯一列。要配置复合主键,您需要像这样在您的DbContext中设置:http://www.luisrozards/2010/11/creating-composite-keys-using-code.html – 2013-05-07 15:34:31

+0

就是这样。我将[Key,Column(Order = 1)]添加到了UserId和[Key,Column(Order = 2)]给RaterId并且它工作。感谢您花时间研究这一点。有趣的是,自动生成的会员表webpages_UsersInRole也有一个复合主键,并且正是我所建模的(使用单个[Key]),但它工作正常。 – aw04 2013-05-07 15:46:49