GraphDiff
GraphDiff copied to clipboard
AssociatedCollection write null into the added entity's column
AssociatedCollection write null into the added entity's column
check the following Code First, MS Tests
public class ManyToManyLeft
{
public ManyToManyLeft()
{
Items = new List<ManyToManyRight>();
}
public int Id { get; set; }
public string Title { get; set; }
public List<ManyToManyRight> Items { get; set; }
}
public class ManyToManyRight
{
public ManyToManyRight()
{
Lefts = new List<ManyToManyLeft>();
}
public int Id { get; set; }
public string Name { get; set; }
public List<ManyToManyLeft> Lefts { get; set; }
public List<Others> Others { get; set; }
}
public class Others
{
public int Id { get; set; }
public string Name { get; set; }
public ManyToManyRight Right { get; set; }
}
public class ManyToManyContext: DbContext
{
public ManyToManyContext()
: base("ManyToManySample")
{
base.Configuration.LazyLoadingEnabled = false;
base.Configuration.ProxyCreationEnabled = false;
}
public DbSet<ManyToManyLeft> LeftSet { get; set; }
public DbSet<ManyToManyRight> RightSet { get; set; }
}
[TestClass]
public class ManyToMany_Tests
{
private const bool ENABLE_LOGGING = true;
#region Setup
[TestInitialize]
public void Setup()
{
using (var context = new ManyToManyContext())// used to load the related EFConfig before starting transactional operations
{
context.Database.ExecuteSqlCommand("DELETE FROM ManyToManyLefts");
context.Database.ExecuteSqlCommand("DELETE FROM ManyToManyRights");
context.Database.ExecuteSqlCommand("DELETE FROM Others");
}
}
#endregion // Setup
#region ToArrayAsync_Test
[TestMethod]
public async Task ToArrayAsync_Test()
{
var l = new ManyToManyLeft { Title = "L1" };
var r1 = new ManyToManyRight { Name = "R1" };
l.Items.Add(r1);
using (var context = new ManyToManyContext())
{
context.LeftSet.Add(l);
await context.SaveChangesAsync();
}
using (var context = new ManyToManyContext())
{
var tmpLeft = await context.LeftSet.Include(m => m.Items)
.AsNoTracking()
.SingleAsync();
Assert.AreEqual(1, tmpLeft.Items.Count);
}
var r2 = new ManyToManyRight { Name = "R2" };
l.Items.Add(r2);
using (var context = new ManyToManyContext())
{
SetLogging(context);
context.UpdateGraph(l,
map => map.AssociatedCollection( with => with.Items));
int affected = await context.SaveChangesAsync();
Assert.AreEqual(2, affected, "right + add relation");
}
using (var context = new ManyToManyContext())
{
var tmpLeft = await context.LeftSet.Include(m => m.Items)
.AsNoTracking()
.SingleAsync();
Assert.AreEqual(2, tmpLeft.Items.Count);
var tmpRight = await context.RightSet
.AsNoTracking()
.SingleAsync(m => m.Name == r2.Name);
}
var r3 = new ManyToManyRight { Name = "R3" };
l.Items.Remove(r2);
l.Items.Add(r3);
using (var context = new ManyToManyContext())
{
SetLogging(context);
context.UpdateGraph(l,
map => map.AssociatedCollection( with => with.Items));
int affected = await context.SaveChangesAsync();
Assert.AreEqual(3, affected, "right + add relation + remove relation");
}
using (var context = new ManyToManyContext())
{
var tmpLeft = await context.LeftSet.Include(m => m.Items)
.AsNoTracking()
.SingleAsync();
Assert.AreEqual(2, tmpLeft.Items.Count);
var tmpRight = await context.RightSet
.AsNoTracking()
.SingleAsync(m => m.Name == r2.Name);
}
}
#endregion // ToArrayAsync_Test
#region SetLogging
internal static void SetLogging(DbContext context)
{
context.Database.Log = sql =>
{
if (ENABLE_LOGGING)
Trace.WriteLine(sql);
};
}
#endregion // SetLogging
}
if I refactor the following part of the code and supply the added entity to the UpdateGraph it's working, but it's missing the point of graph traversal
var r2 = new ManyToManyRight { Name = "R2" };
l.Items.Add(r2);
r2.Lefts.Add(l);
using (var context = new ManyToManyContext())
{
SetLogging(context);
//context.UpdateGraph(l,
// map => map.AssociatedCollection(with => with.Items));
context.UpdateGraph(r2,
map => map.AssociatedCollection(with => with.Lefts));
int affected = await context.SaveChangesAsync();
Assert.AreEqual(2, affected, "right + add relation");
}
Is this maybe the same as #136 ? For me it seems that the GraphDiff method AttachRequiredNavigationProperties does wrong when dealing with associated collections; it overwrites navigation properties on the associated list objects with the input values even if they are null?