我正在尝试实现以多对多关系更新我的实体的函数 - remove or insert
。我需要模型 - 用户可以在多个会议中,会议可以有多个用户
我正在使用EntityFramework Core 2.0.1。因为我发现EF核心2. [x]还不支持多对多的连接,所以我创建了一个自定义连接表。
当我想插入新实体时出现问题 - Attach
(在SaveChanges()
之后)没有将任何更改传播到数据库中,我没有收到任何错误。删除实体正常工作。我使用了关于从source进行更新的想法。使用了很好的扩展名Except
来获取已删除的插入的扩展名AddRange
。
List
方法创建了UserConference
public class IdentityUserCustom : IdentityUser
{
public string ColorProfile { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public virtual ICollection<UserConference> UsersConferences { get; set; }
public virtual ICollection<IdentityUserRole<string>> Roles { get; } = new List<IdentityUserRole<string>>();
}
这导致我认为我是在尝试插入现有记录,实际上是不是我创建UserConference列表的问题?此解决方案可能也存在类似的问题。
<小时/> 为了清晰起见,我将缩短属性和其余代码。
用户实体
扩展了IdentityUser类
public class Conference
{
public int ConferenceId { get; set; }
public virtual ICollection<UserConference> UsersConferences { get; set; }
}
会议实体
public class UserConference
{
public string UserId { get; set; }
public virtual IdentityUserCustom User { get; set; }
public int ConferenceId { get; set; }
public virtual Conference Conference { get; set; }
}
加入表格
[HttpPut]
public async Task<object> UpdateConference([FromBody]ConferenceViewModel model)
{
try
{
using (_unitOfWork)
{
//find conference
var conference =
await _unitOfWork.GetDbContext().Conferences.Include(p => p.UsersConferences)
.FirstOrDefaultAsync(p => p.ConferenceId == model.ConferenceId);
if (conference != null)
{
var usersConferences = new List<UserConference>();
//get UserConference from model and create collection
if (model.UsersConferences.Any())
{
foreach (var userModel in model.UsersConferences)
{
//find existing user
var user = await _userManager.FindByNameAsync(userModel.UserName);
if (user != null)
{
//make relationship
usersConferences.Add(new UserConference { Conference = conference, ConferenceId = model.ConferenceId, User = user, UserId = user.Id });
}
}
}
//get deleted users
var deletedUsers =
conference.UsersConferences.Except(usersConferences, p => (p.UserId, p.ConferenceId)).ToList();
//get newly added users
var addedUsers = usersConferences.Except(conference.UsersConferences,
p => (p.UserId, p.ConferenceId)).ToList();
//remove deleted users
foreach (var deletedUsr in deletedUsers)
{
conference.UsersConferences.Remove(deletedUsr);
}
//add new users
foreach (var addUsr in addedUsers)
{
//check if detached
if (_unitOfWork.GetDbContext().Entry(addUsr).State == EntityState.Detached)
_unitOfWork.GetDbContext().UsersConferences.Attach(addUsr);
//add to existing conference
conference.UsersConferences.Add(addUsr);
}
//commit - SaveChanges()
_unitOfWork.Commit();
}
//just for any response
return "OK";
}
}
catch (Exception e)
{
//log it
}
}
WebApi更新方法
mail = Mail.new
# ..........
# it returns html
mail.body = ERB.new(File.read(File.expand_path("templates/email/main.html"))).result(binding)
# mail.body does contain html now
# ......
mail.attachments["something.pdf"] = File.binread(.....)