1

I have a class structure in entity, the looks something like this:

public class Parent
{
    public int Id { get; set; }

    public List<Child> Children { get; set; }

    //Lots more fields....
}

public class Child
{
    public int Id { get; set; }

    public int ParentId { get; set; }

    [ForeignKey("ParentId")]
    public Parent Parent { get; set; }

    //Lots more fields....
}

I then run the query on these tables using the following code:

Context.Database.Log = s => Debug.Print(s);
var ALL = Stopwatch.StartNew();
var query = context.Parent.Include(x => x.Children).Where(x => //Whatever...).ToList()();
ALL.Stop();
Context.Database.Log = null;

The output from the query debug tells me the query too 773ms eg less than a second, but the timer tells me the whole process took 2 seconds.

Given this , I assume the extra second or so is the time it takes Entity to map the data into the object - can anyone confirm if this is correct?

And more importantly - my question is, what are my options for cutting this time down?

As a note, this code:

Context.Database.Log = s => Debug.Print(s);

will output the actual SQL that is executed to a command window in visual studio.

Alex
  • 3,730
  • 9
  • 43
  • 94
  • 1
    It depends on how much data you query, how many properties your entities have and how many data you receive. You can output the generated query by EF and analyze it directly in your Database. You can also use the [EfProf](https://www.hibernatingrhinos.com/products/efprof) to see how long the query runs and how long ef need to map the data to your models. – Rabban Dec 07 '18 at 12:06
  • Does it log only a single SQL query? Do you get similar results if you immediately run it a second time (with a new Context)? – sellotape Dec 07 '18 at 12:08
  • 2
    It could be due to the overhead of adding the objects to the context, etc. Try specifying AsNoTracking and see what difference that makes. I have seen a noticeable improvement in some cases. https://stackoverflow.com/questions/12211680/what-difference-does-asnotracking-make – Mark Wagoner Dec 07 '18 at 12:13
  • You only want to read data or you want to update them? If you only want to read, use .AsNoTracking(). Also if you dont need to accès to linked data set context.Configuration.LazyLoadingEnabled = false. – LeBigCat Dec 07 '18 at 12:15
  • @mjwills They are taking it from EF log (`Debug.Print(s);`). The message is something like `Completed in NNN ms with result: SqlDataReader`. Which should btw answer to question - the logged time is just to execute the SQL and obtain a data reader. Iterating the result (fetching the data) and converting it to objects (materialization) apparently is not. – Ivan Stoev Dec 07 '18 at 12:15
  • 1
    if you do this second time with new context, are the times the same? There is huge overhead in EF for database initalization (model rebuilding, first time caching etc). You can call `Database.Initialize()` early in the application, even from different thread at startup, which will make it seem like not a big deal. – Krzysztof Skowronek Dec 07 '18 at 12:34

1 Answers1

1

Given this , I assume the extra second or so is the time it takes Entity to map the data into the object - can anyone confirm if this is correct?

Yes, although loading time of mappings improved on Entity Framework, it still takes time.

According to @Mikael Eliasson's answer [1],

  • You can use Cached Db Model
  • You can generate Pre Compiled views
  • You can Generate pre-compiled version of entityframework using n-gen to avoid jitting (I didn't try this approach)
  • You can look for splitting your DbContext into multiple pieces and use multiple DbContexes as per your need.

Hope this helps

Derviş Kayımbaşıoğlu
  • 28,492
  • 4
  • 50
  • 72