Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <blockquote> <p>...Our test was to add a single, uninitialized instance of the class to the database. Using DbContext.Add...</p> </blockquote> <p>Did you make sure that your Code-First model is created and loaded into memory <strong>before</strong> you've called <code>Add</code>? I mean the following: If you use a test code like this ...</p> <pre><code>using (var context = new MyContext()) { var myHugeBusinessObject = CreateItSomeHow(); context.HugeBusinessObjects.Add(myHugeBusinessObject); context.SaveChanges(); } </code></pre> <p>... and it's the first time that you are using the context in your test application <code>Add</code> will actually spent some time to build the EF model in memory before it starts to add the object to the context.</p> <p>You can separate these two steps simply by adding a dummy method before calling <code>Add</code>, for instance something like: </p> <pre><code>context.HugeBusinessObjects.Count(); </code></pre> <p>I've built a test:</p> <pre><code>public class MyClass { public int Id { get; set; } public string P1 { get; set; } // ... P2 to P49 public string P50 { get; set; } public MyClass Child1 { get; set; } // ... Child1 to Child26 public MyClass Child27 { get; set; } } </code></pre> <p>With this I created an object:</p> <pre><code>var my = new MyClass(); MyClass child = my; for (int i = 0; i &lt; 100; i++) { child.Child1 = new MyClass(); child = child.Child1; } child = my; for (int i = 0; i &lt; 100; i++) { child.Child2 = new MyClass(); child = child.Child2; } // and so on up to Child27 </code></pre> <p>So this object graph has 2700 child objects with 50 scalar properties each. Then I tested this code:</p> <pre><code>using (var context = new MyContext()) { var my = CreateWithTheCodeAbove(); context.MyClassSet.Count(); context.MyClassSet.Add(my); context.SaveChanges(); } </code></pre> <p><code>...Count()</code> (= building the EF model) needs roughly <strong>25 seconds</strong>. <code>Add</code> needs <strong>1 second</strong>. (Changing 100 to 1000 in the loops above (having then 27000 objects in the graph) increases the time for <code>Add</code> almost linearly to 9-10 seconds.) This result is independent of setting <code>AutoDetectChangesEnabled</code> to <code>true</code> or <code>false</code>.)</p> <p>The next interesting result: If I add 20 navigation properties more (<code>Child28</code> to <code>Child47</code>) to <code>MyClass</code> the time spent with building the model (<code>Count()</code> in the example code) explodes to <strong>140 seconds</strong>. The duration of <code>Add</code> only increases linearly with the additional properties.</p> <p><strong>So, my hypothesis is: You are not actually measuring the time to add your business object to the context but the time EF needs to build the EF model in memory. The time to build the model seems to grow exponentially with the complexity of the model: Number of navigation properties on a class and perhaps also the number of different involved classes.</strong></p> <p>To separate these steps test with some dummy call like suggested above. If you already have this separation... omg, forget this post.</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload