Ho una web app che chiama un webApi, il mio webApi chiama i miei servizi, e il mio servizio chiama il mio DbContext.
Ho 2 entità, contenuto e file. Queste sono entità separate e memorizzate in tabelle separate.
Ora ho anche una raccolta contro il contenuto, chiamato File. Questo è usato per fare riferimento a un file a un'entità di contenuto.
Il framework Entity ha quindi creato tabelle denominate Content, File e ContentFile. La mia configurazione per il framework di entità, è così
public ContentConfig()
: base()
{
this.HasMany<File>(s => s.Files)
.WithMany(c => c.Contents)
.Map(e =>
{
e.MapLeftKey("ContentId");
e.MapRightKey("FileId");
e.ToTable("ContentFile");
});
}
Per il mio web API, sto inviando i miei dati per i contenuti, che sembra così
Id = 1,
Files = {
{ Id = 1, Name = "Test" }
}
Qui ho un'entità di contenuto che esiste già con un Id di 1 e un File che esiste già con un Id di 1. Sto passando questo come mi aspetterei che Entity Framework crei una relazione tra le 2 entità.
Nel mio servizio, ho questo codice.
public Task<int> AddOrUpdateAsync(Content content)
{
// attach all files
foreach (var file in content.Files)
_context.Entry(file).State = EntityState.Modified;
_context.Entry(content).State = EntityState.Modified;
return _context.SaveChangesAsync();
}
Tutto ciò sembra fare, è aggiornare la mia entità di contenuto e aggiornare l'entità del file. Non è stata inserita alcuna relazione? Qualcuno può aiutarmi a inserire la relazione? Cosa succede se esiste già nell'aggiornamento? La struttura dell'entità verrà fuori per me?
Sembra così difficile trattare con le entità quando tutto è scollegato ?? O sono solo io? Nel mio test unitario funziona, ma le entità non sono disconnesse.
Non sono sicuro che abbia qualcosa a che fare con questo, ma sto usando AutoMapper per creare le mie entità dai miei modelli webApi.
Quando lavori in modalità disconnessa, potrebbe essere una soluzione per caricare l'entità originale nel tuo metodo aziendale (lato server) e lavorare con le proprietà di navigazione collegate e salvarle in un secondo momento.
ad esempio il seguente codice mostra come salvare una categoria con i prodotti figlio in uno scenario disconnessi:
protected void UpdateCategoryWithProducts(Category entity)
{
/*--- Get Original Entity ---*/
var originalMaster = this.GetQuery("Products").Where(x => x.CategoryId == entity.CategoryId).FirstOrDefault();
/*--- Master ---*/
this.Context.ChangeEntityStateToEdited(originalMaster, entity);
if (entity.Products != null)
{
/*--- Get Lists ---*/
var addedList = entity
.Products
.Where(y => y.ProductId == 0)
.ToList();
var deletedList = originalMaster
.Products
.Where
(
x =>
(
!entity.Products
.Select(y => y.ProductId)
.Contains(x.ProductId)
)
)
.ToList();
var editedList = entity.Products
.Where
(
y => originalMaster
.Products
.Select(z => z.ProductId)
.Contains(y.ProductId)
)
.ToList();
/*--- Delete ---*/
deletedList.ForEach(deletedProduct =>
{
originalMaster.Products.Remove(deletedProduct);
this.Context.ChangeEntityStateToDeleted(deletedProduct);
});
/*--- Edit ---*/
editedList.ForEach(editedProduct =>
{
var originalProduct = originalMaster.Products.Where(x => x.ProductId == editedProduct.ProductId).FirstOrDefault();
this.Context.ChangeEntityStateToEdited(originalProduct, editedProduct);
});
/*--- Add ---*/
addedList.ForEach(addedProduct =>
{
originalMaster.Products.Add(addedProduct);
});
}
/*--- Save in context ---*/
this.Context.Categories.Update(originalMaster);
this.Context.SaveChanges();
}