EFCore.BulkExtensions
EFCore.BulkExtensions copied to clipboard
BulkInsert not working
Why does this work?
List<BrepEntity> brepjes = new List<BrepEntity>();
for (int i = 0; i < 100; i++)
{
brepjes.Add(new BrepEntity()
{
Polygons = new List<PolygonEntity>()
{
new PolygonEntity()
{
Vertices = new List<VectorEntity>()
{
new VectorEntity() { X = 123, Y = 2348.324f, Z = 234293784.1f },
}
},
new PolygonEntity()
{
Vertices = new List<VectorEntity>()
{
new VectorEntity() { X = 334, Y = 244648.324f, Z = 909793784.1f },
}
}
}
});
}
Stopwatch stopwatch = Stopwatch.StartNew();
_context.BulkInsert(brepjes, options => options.IncludeGraph = true);
_context.BulkSaveChanges();
stopwatch.Stop();
return stopwatch.ElapsedMilliseconds;
But this does not?
List<GridInfoEntity> test = new List<GridInfoEntity>()
{
new GridInfoEntity()
{
GridInfoX = new List<GridInfoXEntity>()
{
new GridInfoXEntity("Label", 123),
},
GridInfoY = new List<GridInfoYEntity>()
{
new GridInfoYEntity("Label", 456),
},
GridInfoZ = new List<GridInfoZEntity>()
{
new GridInfoZEntity("Label", 789),
},
}
};
Stopwatch stopwatch = Stopwatch.StartNew();
_context.BulkInsert(test, options => options.IncludeGraph = true);
_context.BulkSaveChanges();
stopwatch.Stop();
return stopwatch.ElapsedMilliseconds;
I am getting this error, which is incorrect:
Missing Column : GridInfoId On entity : GridInfoXEntity On Table : [Domain].[GridInfo]
If I use AddRange for the not working example, it works. I am therefore sure that both the tables and columns exist.
After 13 hours of testing and 14 minutes after making this post, I figured out the problem. BulkInsert cannot handle schemas!
[Table("GridInfo", Schema = "Domain")]
When I removed this line of code, it worked. Perhaps you want to check that out.
Could you add entire code of class GridInfoEntity and GridInfoZEntity or write a Test for the issue.
Yes, of couse. See below (screenshot for readability + copy paste):
GridInfoEntity
[Table("GridInfo", Schema = "Domain")] public class GridInfoEntity : Entity { public virtual ICollection<GridInfoXEntity> GridInfoX { get; set; } public virtual ICollection<GridInfoYEntity> GridInfoY { get; set; } public virtual ICollection<GridInfoZEntity> GridInfoZ { get; set; } }
GridInfoXEntity
[Table("GridInfo.X", Schema = "Domain")] public class GridInfoXEntity : Entity { public GridInfoXEntity(string label, float value) { ValueX = value; Label = label; }
public GridInfoXEntity()
{
}
public float ValueX { get; set; }
public string Label { get; set; }
public virtual GridInfoEntity GridInfo { get; set; }
}
Exactly the same applies to the Y and Z variant (I double checked in my code).
And for the Brep-chain:
BrepEntity
public class BrepEntity : Entity { public virtual ICollection<PolygonEntity> Polygons { get; set; } }
PolygonEntity
public class PolygonEntity : Entity { public int BrepId { get; set; } public virtual BrepEntity Brep { get; set; } public virtual ICollection<VectorEntity> Vertices { get; set; } }
VectorEntity
public class VectorEntity : Entity { public float X { get; set; } public float Y { get; set; } public float Z { get; set; }
public int PolygonId { get; set; }
public virtual PolygonEntity Polygon { get; set; }
}
The only difference appears to be the schema. Once I removed it, everything worked as expected. And I remember from last week that I got exception that actually used the schema name. It said that the schema name did not exist (while it definitely did). I guess somewhere in your code, you are not handling schemas. Is that possible?
For now, I disabled schemas in my code base (hopefully temporarily, because my database is not nicely structured anymore when viewing it in SMSS).
Schemas are actually supported with main Bulk ops. But IncludeGraph often had exceptions. I will lookup into it more. In the meantime you could try to call 2 times BulkInsert, instead of using IncludeGraph.
How do you mean that exactly? I interpreted IncludeGraph as: include all children so that all gets added. In this particular example, you mean storing the X-values, Y-values, Z-values and grid infos themselves as separate calls?
I guess that would work here, but in my actual project this would get too messy (I have referred a different post 38 minutes ago). I can live with not having schemas for the time being.
Yes, that's right.
Thank you Boris for you quick replies. I will keep an eye on this post and would be more than happy to contribute to solving this problem wherever I can. Just let me know.