В настоящее время я работаю со следующей первой моделью кода EF, которая имеет отношение многие ко многим между человеком и тегом.
public class person
{
public Person()
{
this.Tags = new List<Tag>();
}
public int Id { get; set; }
public string Name { get; set; }
public virtual ICollection<Tag> Tags { get; set; }
}
public class Tag
{
public Tag()
{
this.People = new List<Person>();
}
public int Id { get; set; }
public string Name { get; set; }
public virtual ICollection<Person> People { get; set; }
}
public MyContext : DbContext
{
public DbSet<Person> People { get; set; }
public DbSet<Tag> Tags { get; set; }
}
Затем я передаю модель Json контроллеру MVC, которыйсодержит существующего человека и обновляет имя человека, а также добавляет или удаляет теги из списка тегов этого человека.
У меня были некоторые проблемы с правильной привязкой тегов к человеку.После долгих проб и ошибок, я пришел к следующему методу, который работает:
[HttpPost]
public JsonResult Save(Person person)
{
//get ids of all tags that are associated with this person.
var tagIds = new List<int>();
foreach (var tag in person.Tags)
{
tagsIds.Add(tag.Id);
}
//clone the person minus the tags
var personToSave = person;
personToSave.Tags = new List<Tag>();
var context = new MyContext();
var existingTags = (from t in context.Tags
where t.People.Count > 0 && t.People.All(p => p.Id == person.Id)
select t).ToList();
//attach the person, so updates to the person object will save.
context.Entry(personToSave).State = EntityState.Modified;
if (tagIds.Count > 0)
{
//add new tags
var tags = context.Tags.Where(t => tagIds.Contains(t.Id));
foreach (var tag in tags)
{
//check if tags has no people and not already associated to this person.
if (tag.People.Count == 0 || tag.People.First(p => p.Id == person.Id) == null)
{
personToSave.Tags.Add(tag);
}
}
//remove tags that exist for this person, but were not specified in the list of
//tags on the person object that was passed into the method.
foreach(var existingTag in existingTags)
{
if (!tagIds.Contains(existingTag.Id)
{
context.Tags.Find(existingTag.Id).People.Remove(person);
}
}
}
//Finally if no tags were passed in the model and the person has tags, remove them.
if (tagsIds.Count == 0 && existingTags.Count > 0)
{
foreach (var oldTag in existingTags)
{
context.Tags.Find(oldTag.Id).People.Remove(person);
}
}
context.SaveChanges();
var message = string.Format("Saved {0} with {1} tags", person.Name, person.Tags.Count);
return Json(new {message});
}
Весь этот код выглядит как большая работа по добавлению / удалению тегов у человека.Я все еще довольно новичок в Entity Framework, поэтому я чувствую, что, возможно, что-то упустил.Я хотел бы знать, есть ли у меня лучший способ сделать это.Кроме того, обратите внимание, что это было первое, что я смог получить на работе, так что, возможно, есть дополнительные рефакторинги, которые можно применить.