【问题标题】:EntityFramework 4.1, context.Entities.Add sometimes set FK to NULLEntityFramework 4.1,context.Entities.Add 有时将 FK 设置为 NULL
【发布时间】:2013-01-27 15:09:06
【问题描述】:

我遇到了这个奇怪的问题,花费的时间比它应该的要长。

我的主要问题是: 在添加实体时,什么可能导致 EF 4.1 Code First 将外键设置为 NULL

问题是这样的:我有一个用户列表,如果这些用户不存在,则必须将它们插入到我的数据库中。

我有这样的事情:

foreach (var u in usersFromFile) {
    var userProfile = context.Users
        .FirstOrDefault(user=>
            user.EmployeeId == u.EmployeeId && user.CompanyId == 1);
    if (userProfile == null) {
        User newUser = new User();
        newUser.EmployeeId = u.EmployeeId;
        newUser.CompanyId = 1;
        context.Users.Add(newUser); //This will sometimes set CompanyId = NULL
    }
}
context.SaveChanges();

某些用户无法正确添加到用户表中。 他们得到 CompanyId == NULL,因此他们不属于公司。

我也试过像这样直接注入 SQL:

var query = @"INSERT INTO [dbo].[Users] 
              ([CompanyId],[EmployeeId]) VALUES (3,@emplid)";

context.Database.ExecuteSqlCommand(query, new SqlParameter[] {
    new SqlParameter("emplid", u.EmployeeId)});
  • 我试图访问公司对象上的用户列表。那是行不通的。
  • 我尝试使用 context.Users.Create() 而不是 new User()。不会改变任何东西。
  • 我试过注入SQL,还是同样的问题。如果从 Studio Manager 运行,则该确切的 SQL 有效。
  • 每次添加后我都尝试过 context.SaveChanges(),没有任何改变。

我知道要添加的实体的状态是正确的,在 CompanyId 设置为 NULL 的情况下也是如此。 我的底层数据库可能有问题吗?

非常感谢您的宝贵时间和帮助!

【问题讨论】:

    标签: c# sql entity-framework


    【解决方案1】:

    我最终将用户列表转换为一系列 SQL 语句,并通过 context.Database.ExecuteSqlCommand(sql) 运行它们。

    它很脏,但它可以工作。

    如果有人对为什么用户实体上的 FK CompanyId 有时设置为 NULL 有任何好的想法,如果您能分享您的想法,我们将非常高兴。

    【讨论】:

      【解决方案2】:

      尝试以下方法:

       foreach (var u in usersFromFile) {
          if (context.Users.Any(
                user=>
                  user.EmployeeId == u.EmployeeId && user.CompanyId == 1)
             ) 
          {
              User newUser = new User();
              newUser.EmployeeId = u.EmployeeId;
              newUser.CompanyId = 1;
              context.Users.Add(newUser); //This will sometimes set CompanyId = NULL
          }
      }
      context.SaveChanges();
      

      Any() 函数根据给定查询检查用户是否存在。

      另外,不要忘记添加 context.savechanges 以确保每条添加的记录都放入数据库中。

      最后,您检查了 user.CompanyId = 1,是否应该 == 1

      【讨论】:

      • 感谢您指出我的示例代码中的一些缺陷。对于这个简单的案例,我可以使用 Any,但如果实体存在,我最终需要对其进行更改。我更新了我的初始条目以反映您发现的缺陷。可悲的是,我的代码中仍然存在错误。 CompanyId 有时仍设置为 NULL。
      • 您可以尝试从实体上下文中获取公司并将用户添加到公司的方法,而不是将实体直接添加到上下文并说它具有 Id 1。试试: var comp = context.Companys.Where(c => c.Id == 1); comp.Add(newUser); context.savechanges();
      • 不幸的是......“我试图访问公司对象上的用户列表。这不起作用。”通过访问,我的意思是检索和添加。
      • 所以没有属性Company.User?那么你有一个不同的问题,你应该映射一个虚拟的。如果您使用的是代码优先方法,请添加 public IEnumerable User {get; set;} 到公司实体和公共虚拟公司 {get; set;} 到用户实体。如果首先使用 DB,请确保 USER 表有一个指向公司的外键并刷新您的方案
      • 一个属性是虚拟 IEnumerable 用户,但如果我通过它添加我的用户,它不会改变任何东西。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-12-22
      • 1970-01-01
      • 2022-01-20
      • 2011-05-29
      • 1970-01-01
      相关资源
      最近更新 更多