2015-04-22 28 views
1

我正在尝试更新我的一个实体中的列表。这是我在做什么:对未注册实体的更改

var loggedInUserId = User.Identity.GetUserId(); 
var applicationDbContext = new ApplicationDbContext(); 

var x = Request["groupCode"]; 
var affectedGroup = db.StudentGroups.FirstOrDefault(s => s.Code == x); 
var groupId = affectedGroup.Id; 
if (affectedGroup != null) 
{ 
    if (affectedGroup.StudentIds == null) 
    { 
     affectedGroup.StudentIds = new List<string>(); 
    } 
    if (affectedGroup.StudentIds.Contains(loggedInUserId)) 
    { 
     TempData["ErrorMessage"] = "You are already a member of this group"; 
    } 
    else 
    { 
     affectedGroup.StudentIds.Add(loggedInUserId); 
     db.SaveChanges(); 
    } 
} 

这里是我的StudentGroup型号:

public class StudentGroup 
{ 
    public int Id { get; set; } 
    [Required(ErrorMessage = "The group must have a name.")] 
    public string Name { get; set; } 
    [Required(ErrorMessage = "The code is required.")] 
    public string Code { get;set; } 
    public string Description { get; set; } 

    [Display(Name="Members")] 
    public IList<string> StudentIds { get; set; } 
} 

的问题是,StudentIds总是空,当我在调试器中运行,即使当我通过步骤它,Id确实被添加。 我是ASP.NET MVC的新手,所以请牢记这一点。

+0

你应该使用处置您的上下文的'使用'块 – DLeh

+0

组代码存在,它通过POST从表单中获取。我确定它与我的测试数据相符。 – FreHu

+0

它实际上是一个多对多的关系,我以前在存储实际用户时遇到了一些问题。我认为这与模型在不同的上下文中有关系(学生是基于默认情况下的IdentityUser,当我创建项目时已经设置了该模型,而StudentGroup是在我创建的上下文中),但是我没有记住问题的确切细节。正如我所说,我是新手,只是想让它工作,然后我可以让它工作正确。 – FreHu

回答

0

我会推荐使用交叉引用表来处理这个功能。你可以让你的StudentGroup模型有一个Id,Code,Name和Description字段;然后创建一个xStudentsInStudentGroup表,其中存储StudentId和StudentGroupId以将这两者关联起来。

其余的代码将是半相似的。你仍然可以用同样的方法得到groupId,但是一旦你拥有了它,你可以从xStudentsInStudentGroup中取出所有的学生ID并使用它们。

if(context.xStudentsInStudentGroup.Any(x => groupId == x.StudentGroupId && x.StudentId == loggedInUserId)) 
{ 
    //Already in 
} 
else 
{ 
    var xStudent = new xStudentsInStudenGroup() 
    { 
    StudentId = loggedInUserId 
    StudentGroupId = GroupId 
    }; 
    context.Insert(xStudent);//This depends on how you add new records 
    context.SaveChanges(); 
} 

我也会看看你是如何设置你的控制器。您应该有一个基础,可以为每个操作创建并部署新的数据库上下文。或者做一个使用语句,如前所述清理上下文。

- EDIT-- 我不推荐你这样做的原因是因为似乎没有任何意义,你可以保存一个整数列表并让它更新。如果你在其他领域有这样的工作,那么你的问题可能只是你将StudentIds对象作为字符串列表而不是整数。

0

我认为你可以简化你的代码,使它像这样的工作:

var x = Request["groupCode"]; 
var affectedGroup = db.StudentGroups.FirstOrDefault(s => s.Code == x); 
var groupId = affectedGroup.Id; 

if (affectedGroup != null && !affectedGroup.Any()) 
    { 
     affectedGroup.StudentIds = new List<string>(); 
     affectedGroup.StudentIds.Add(loggedInUserId); 
    } 
else if (affectedGroup.StudentIds.Contains(loggedInUserId)) 
    { 
     TempData["ErrorMessage"] = "You are already a member of this group"; 
    } 

db.SaveChanges(); 

此外,您可能需要使用EntityState.Modified或EntityState.Add确保EF意识到的变化。

+0

这不能解决我的问题。当代码再次运行时,即使我调用SaveChanges,studentIds也为null。 – FreHu

+0

调试时,loggedInUserId是否有值?另外,请检查更新后的答案,以查看EntityState是否有所帮助。 –

0

好像你想收到你有组明确包括使用包括方法的学生证时,不要使用EF延迟加载,即:

db.StudentGroups.Include(s => s.StudentIds).FirstOrDefault(s => s.Code == x);