我有一份调查,其中包含问题以及哪些用户可以/将参与调查。
像这样
public virtual ICollection<User> ParticipatingUsers { get; set; }
public virtual ICollection<Question> SpecificQuestions { get; set; }
但是,由于 ajaxy 解决方案,我首先创建问题,然后简单地将我创建的问题的 ID 与调查数据一起发送。所以我需要做的就是更改问题的排序索引,然后在我的调查中添加对它的引用。
当涉及到用户时,他们属于公司实体,我只想从调查中引用他们而不是拥有他们。
但是目前我在我的操作方法(.net mvc)中获得了问题和用户的所有 id,因此目前我加载所有问题和用户并将它们附加到我的调查实体,然后再将调查发送到存储库。
但是,当我的 Repository 在 dbset 上调用 Add 时,它会克隆用户和问题数据,而不是简单地引用现有数据。
我迷路了,我已经通过添加 [Foreignkey] 解决了正常导航属性的这个确切问题,但我不知道这将如何与 ICollection 一起使用
为了完整性
这是我接收数据的操作方法
[HttpPost]
[FlexAuthorize(Roles = "RootAdmin")]
public ActionResult SaveSurvey(EditSurveyViewModel editModel)
{
if (!ModelState.IsValid)
{
//We dont bother to send this in so we need to fetch the list again
editModel.CompanyList = _companyRepository.GetAll();
List<string> deletionList = new List<string>();
//We clear out all questions from the state as we have custom logic to rerender them with the correct values
foreach (var modelstateItem in ModelState)
{
if (modelstateItem.Key.StartsWith("Questions"))
{
deletionList.Add(modelstateItem.Key);
}
}
foreach (string key in deletionList)
{
ModelState.Remove(key);
}
return View("EditSurvey", editModel);
}
List<Question> questionlist = new List<Question>();
int sort = 1;
Question q;
//We have questions sent in from the ui/client
if (editModel.Questions != null)
{
//Go trough each questions sent in
foreach (var question in editModel.Questions)
{
//if it's a page break, just assign our new question the sent in one and set sort index
if (question.IsPageBreak)
{
q = question;
q.SortIndex = sort;
}
else
{
//It's a question and all questions are already created with ajax from the client
//So we simply find the question and then set sort index and tie it to our survey
q = _questionRepository.GetById(question.Id);
q.SortIndex = sort;
}
questionlist.Add(q);
sort++;
}
}
//assign the new sorted questions to our Survey
editModel.Item.SpecificQuestions = questionlist;
List<User> userlist = new List<User>();
foreach (int id in editModel.SelectedUsers)
{
userlist.Add(_userRepository.GetById(id));
}
editModel.Item.ParticipatingUsers = userlist.ToList();
_surveyRepository.SaveSurveyBindAndSortQuestionsLinkUsers(editModel.Item);
return RedirectToAction("Index");
}
这是发送该方法的视图模型
public class EditSurveyViewModel
{
public Survey Item { get; set; }
public IEnumerable<Question> Questions { get; set; }
public bool FullyEditable { get; set; }
public IEnumerable<Company> CompanyList { get; set; }
public IEnumerable<int> SelectedUsers { get; set; }
}
最后这里是repo方法(到目前为止我只实现了插入,没有更新)
public void SaveSurveyBindAndSortQuestionsLinkUsers(Survey item)
{
if (item.Id == 0)
{
Add(item);
}
ActiveContext.SaveChanges();
}
更新/编辑
Moho:你当然是对的,我觉得很遗憾我在测试一些东西并忘记在粘贴之前重置方法。我已经更新了上面的操作方法。
斯劳玛:抱歉没有详细说明,这里有更多。
我所有的存储库都是这样的
public class EFSurveyRepository : Repository<Survey>, ISurveyRepository
所以他们继承了一个通用存储库并实现了一个接口通用存储库(我们在上面的代码中使用的部分,看起来像这样)
public abstract class Repository<T> : IRepository<T> where T : class
{
public EFDbContext ActiveContext { get; private set; }
private readonly IDbSet<T> dbset;
public Repository()
{
this.ActiveContext = new EFDbContext("SurveyConnection");
dbset = ActiveContext.Set<T>();
}
public virtual void Add(T entity)
{
dbset.Add(entity);
}
public virtual T GetById(int id)
{
return dbset.Find(id);
}
我在数据库中注意到我的用户表(用于用户实体)现在包含一个我不希望它拥有的 Survey_Id 字段。我想要一个多对多,其中许多调查可以链接到许多用户(相同的用户),但用户应该在实体方面仍然只属于公司的一个部门。
另外,现在当我运行代码时(在我更正了我的操作方法之后),我收到以下错误:
An entity object cannot be referenced by multiple instances of IEntityChangeTracker.
没有 InnerException,只有当我尝试添加新调查时。