Problem
You want to effectively get an entity that is just used to show actions that are not updated. And you want to do it in a codefirst way.
Solution Solutions
A very common behavior, especially a website, is simply to let the user browse the data. In most cases, the user does not update the data. In this case, you can improve your code performance by avoiding contextual caches and modifying traces, and you can use the Asnotracking method very simply.
Let's assume you have an application to manage Doctor (doctor) appointments (appointment), your model as Figure 13-5.
Figure 13-5. A model for managing doctors and their appointments
First , This example is implemented in the codefirst Way of EF ., created our entity classes, company, Doctor, and appointment in Listing 13-6.
Listing 13-6. The company, Doctor,and appointment.entity Object
public class Company
{
Public Company ()
{
Doctors = new hashset<doctor> ();
}
public int CompanyID {get; set;}
public string Name {get; set;}
Public virtual icollection<doctor> Doctors {get; set;}
}
public class Doctor
{
Public Doctor ()
{
appointments = new hashset<appointment> ();
}
public int Doctorid {get; set;}
public string Name {get; set;}
public int CompanyID {get; set;}
Public virtual icollection<appointment> Appointments {get; set;}
Public virtual company company {get; set;}
}
public class Appointment
{
public int Appointmentid {get; set;}
Public System.DateTime appointmentdate {get; set;}
public string Patient {get; set;}
public int Doctorid {get; set;}
Public virtual Doctor Doctor {get; set;}
}
Next, in Listing 13-7, we create a way to access EF in Codefirst mode, DbContext object
Listing 13-7. DbContext Object
public class Recipe3context:dbcontext
{
Public Recipe3context ()
: Base ("recipe3connectionstring")
{
Disable Entity Framework Model compatibility
Database.setinitializer<recipe3context> (NULL);
}
protected override void Onmodelcreating (Dbmodelbuilder modelBuilder)
{
Modelbuilder.entity<appointment> (). ToTable ("Chapter13.appointment");
Modelbuilder.entity<company> (). ToTable ("Chapter13.company");
Modelbuilder.entity<doctor> (). ToTable ("Chapter13.doctor");
}
Public dbset<appointment> Appointments {get; set;}
Public dbset<company> Companies {get; set;}
Public dbset<doctor> Doctors {get; set;}
}
Next we add the App. Config to the project and include the following listing 13-8 code into the ConnectionString section
Listing 13-8. Connection String
<connectionStrings>
<add name= "Recipe3connectionstring"
Connectionstring= "Data source=.;
Initial catalog=efrecipes;
Integrated security=true;
Multipleactiveresultsets=true "
Providername= "System.Data.SqlClient"/>
</connectionStrings>
To get doctors and companies and to keep them from being added to the context object, we link the Asnotracking method to the query that gets the entity, as in Listing 13-9.
Listing 13-9. Doing a simple Query Using the asnotracking Method
using (var context = new Recipe3context ())
{
var company = new company {Name = "Paola Heart Center"};
var Doc1 = new Doctor {Name = "Jill Mathers", company = company};
var doc2 = new Doctor {Name = "Robert Stevens", company = company};
var App1 = new Appointment
{
Appointmentdate = DateTime.Parse ("3/18/2010"),
Patient = "Karen Rodgers",
Doctor = Doc1
};
var app2 = new Appointment
{
Appointmentdate = DateTime.Parse ("3/20/2010"),
Patient = "Steven Cook",
Doctor = doc2
};
Context. Doctors.add (Doc1);
Context. Doctors.add (DOC2);
Context. Appointments.add (APP1);
Context. Appointments.add (APP2);
CONTEXT.COMPANIES.ADD (company);
Context. SaveChanges ();
}
using (var context = new Recipe3context ())
{
Console.WriteLine ("Entities tracked in the context for doctors ...");
Executing a query with the asnotracking () method
Context. Doctors.include ("Company"). Asnotracking (). ToList ();
Console.WriteLine ("Number of entities loaded into the context with asnotracking: {0}",
Context. Changetracker.entries (). Count ());//output: 0
Do not execute queries without the Asnotracking () method
Context. Doctors.include ("Company"). ToList ();
Console.WriteLine ("Number of entities loaded into context without asnotracking: {0}",
Context. Changetracker.entries (). Count ());//output: 3
}
The output results are as follows:
Entities tracked in context for doctors ...
Number of entities loaded to context with asnotracking:0
Number of entities loaded into context without asnotracking:3
How it works
When we link the Asnotracking method to your query, the results returned from the query are not tracked by the context. In our case, we have shown the Doctor Comanpies.
By default, your query results are tracked by the context, which makes it easier to update and delete, but at the expense of more memory and CPU load. Concatenate more objects into the application, such as browsing the product on an ecommerce site, using the asnotracking option, to save more resources, Make your application more performance-efficient.
Without caching a query result, you have to instantiate the query every time. Typically, to make a modification trace available, EF will not need to instantiate an instance that already exists in a context.
When you include the asnotracking option (such as our listing 13-9), it affects only the entities of the current query. It does not affect subsequent queries that do not contain the asnotracking option, such as the listing 13-9 demo
Entity Framework 6 Recipes 2nd Edition (13-3)---read-only access get entities