Wie setze ich eine Collection-Eigenschaft mit FKs?

Ich habe einBusiness und einCategory Modell.

JederBusiness hat vieleCategories über eine exponierte Sammlung (Category missachtet dieBusiness Entität).

Hier ist meine Controller-Aktion:

[HttpPost]
[ValidateAntiForgeryToken]
private ActionResult Save(Business business)
{
  //Context is a lazy-loaded property that returns a reference to the DbContext
  //It's disposal is taken care of at the controller's Dispose override.
  foreach (var category in business.Categories)
   Context.Categories.Attach(category);

  if (business.BusinessId > 0)
   Context.Businesses.Attach(business);
  else
   Context.Businesses.Add(business);

   Context.SaveChanges();
   return RedirectToAction("Index");
}

Nun gibt es mehrerebusiness.Categories das haben ihreCategoryId auf ein bestehendes setzenCategory (dasTitle Eigentum vonCategory fehlt tho).

Nach dem SchlagenSaveChanges und nachladen derBusiness vom Server, derCategories sind nicht da.

Meine Frage ist also, wie man richtig einstelltBusiness.Categories mit einem gegebenen Array von bestehendenCategoryIds.

Beim Anlegen eines neuenBusiness jedoch das FolgendeDbUpdateException Ausnahme wird beim Aufruf ausgelöstSaveChanges:

Beim Speichern von Entitäten, die keine Fremdschlüsseleigenschaften für ihre Beziehungen verfügbar machen, ist ein Fehler aufgetreten. Die EntityEntries-Eigenschaft gibt null zurück, da eine einzelne Entität nicht als Quelle der Ausnahme identifiziert werden kann. Die Behandlung von Ausnahmen beim Speichern kann vereinfacht werden, indem Fremdschlüsseleigenschaften in Ihren Entitätstypen verfügbar gemacht werden. Weitere Informationen finden Sie in der InnerException.

Innere Ausnahme (OptimisticConcurrencyException):

Das Speichern von Aktualisierungs-, Einfüge- oder Löschanweisungen wirkte sich auf eine unerwartete Anzahl von Zeilen aus (0). Entitäten wurden möglicherweise geändert oder gelöscht, seit Entitäten geladen wurden. Aktualisieren Sie die ObjectStateManager-Einträge.

Aktualisieren

Nach der Antwort ist hier der Update-Code:

var storeBusiness = IncludeChildren().SingleOrDefault(b => b.BusinessId == business.BusinessId);
var entry = Context.Entry(storeBusiness);
entry.CurrentValues.SetValues(business);
//storeBusiness.Categories.Clear();

foreach (var category in business.Categories)
{
  Context.Categories.Attach(category);
  storeBusiness.Categories.Add(category);
}

Beim anrufenSaveChangesIch bekomme folgendesDbUpdateException:

Beim Speichern von Entitäten, die keine Fremdschlüsseleigenschaften für ihre Beziehungen verfügbar machen, ist ein Fehler aufgetreten. Die EntityEntries-Eigenschaft gibt null zurück, da eine einzelne Entität nicht als Quelle der Ausnahme identifiziert werden kann. Die Behandlung von Ausnahmen beim Speichern kann vereinfacht werden, indem Fremdschlüsseleigenschaften in Ihren Entitätstypen verfügbar gemacht werden. Weitere Informationen finden Sie in der InnerException.

So sehen die Business / Category-Modelle aus:

public class Business
{
  public int BusinessId { get; set; }

  [Required]
  [StringLength(64)]
  [Display(Name = "Company name")]
  public string CompanyName { get; set; }

  public virtual BusinessType BusinessType { get; set; }

  private ICollection<Category> _Categories;
  public virtual ICollection<Category> Categories
  {
    get
    {
      return _Categories ?? (_Categories = new HashSet<Category>());
    }
    set
    {
      _Categories = value;
    }
  }

  private ICollection<Branch> _Branches;
  public virtual ICollection<Branch> Branches
  {
    get
    {
      return _Branches ?? (_Branches = new HashSet<Branch>());
    }
    set
    {
      _Branches = value;
    }
  }
}

public class Category
{
  [Key]
  public int CategoryId { get; set; }

  [Unique]
  [Required]
  [MaxLength(32)]
  public string Title { get; set; }

  public string Description { get; set; }

  public int? ParentCategoryId { get; set; }
  [Display(Name = "Parent category")]
  [ForeignKey("ParentCategoryId")]
  public virtual Category Parent { get; set; }

  private ICollection<Category> _Children;
  public virtual ICollection<Category> Children
  {
    get
    {
      return _Children ?? (_Children = new HashSet<Category>());
    }
    set
    {
      _Children = value;
    }
  }
}

Nur um es noch einmal deutlich zu machen, dieCategory Ich halte an bestehenden / neuenBusinessEs ist bereits in der DB vorhanden und verfügt über eine ID, mit der ich es anhänge.

Antworten auf die Frage(3)

Ihre Antwort auf die Frage