Chủ Nhật, 29 tháng 5, 2016

Expression vs Func with Entity Framework

Sometimes developers don't know whether they should use a Func<> or an Expression<Func<>> with the Entity Framework and LINQ. The distinction was critical in a situation I faced today.
Our application was having performance problems, and Red Gate's excellent ANTS profiling tool pointed to a method that, reduced to its essence, was like what you see below. Context is an Entity Framework context, and MyEntities is one of the entity tables in the context. 

IEnumerable<MyEntity> LoadMyEntities(Expression<Func<MyEntity, bool>> predicate)
{
    return Context.MyEntities.Where(predicate);
}

The idea is that a caller can pass in a predicate in the form of a Lambda. The compiler will turn the Lambda into a LINQ Expression, which can be passed to the method in the 'predicate' parameter.

int id;
// Set the id somehow and then...
var theEntity = LoadMyEntities(e => e.UniqueId == id).Single();

The profiler told us that LoadMyEntities was being called many, many times and it was taking a large fraction of our CPU time. The simple change below solved the problem. Can you guess why?

public IEnumerable<MyEntity> LoadMyEntities(Func<MyEntity, bool> predicate)
{
    return Context.MyEntities.Where(predicate);
}

The parameter is now a Func<> instead of an Expression<Func<>>. The reason this makes a difference is that a predicate that's in the form of an Expression is passed to SQL server, but a predicate that's passed as a Func is not. Normally, you'd want SQL Server to do as much for you as possible, and an Expression would be the right choice, but in this case we'd like to pre-load the entire table in the context -- which is exactly what a Func will do. (This the same point I made in Falling in Love with LINQ, Part 7.) Step by step...
  1. The Where extension method has two flavors. One extends IQueryable and takes an Expression parameter. The other extends IEnumerable and takes a Func.
  2. Because 'predicate' is now a Func, the Where that extends IEnumerable is used.
  3. The Entity Framework's fluent interface for constructing SQL queries is based on IQueryables, not IEnumerables. Therefore, the fluency stops just before the Where. The part of the statement that gets passed to the Entity Framework is just Context.MyEntities.
  4. Context.MyEntities therefore returns the entire table to the context.
  5. The entire table is now filtered with the predicate, and the value we really want is returned.
  6. The next time the method is called, the Entity Framework realizes that the record we want is already in the context. (In my case, we were querying by the primary key, and EF is apparently smart enough to know that if there's a record in the context with that ID, it won't find an additional such record in the database.) Since we don't go out to SQL Server, we save lots of time. Obviously there are occasions when you would not want this, but in our case it was exactly what we wanted. The table was relatively small, and the same context was queried hundreds of times.
In the original version, the predicate was an Expression, so the compiler used the Where that extends IQueryable. The predicate was thus passed to SQL Server, which dutifully returned just one row to the context. The next time we called LoadMyEntities, Entity Framework had to call SQL Server again.
The change from Expression to Func gave us a 6-fold reduction in CPU usage! But again, your situation may call for an Expression. The important thing is to know the difference, and now you do!

Link: http://fascinatedwithsoftware.com/blog/post/2012/01/10/More-on-Expression-vs-Func-with-Entity-Framework.aspx
Read More »

Thứ Năm, 26 tháng 5, 2016

Handler "has a bad module "ManagedPipelineHandler" in its module "

Ran command:
%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_regiis.exe -i
If I had been on a 32 bit system, it would have looked like the following:
%windir%\Microsoft.NET\Framework\v4.0.21006\aspnet_regiis.exe -i
Read More »

Thứ Năm, 24 tháng 3, 2016

ProxyCreationEnabled and LazyLoadingEnabled

If DbContext.Configuration.ProxyCreationEnabled is set to false, DbContext will not load child objects for some parent object unless Include method is called on parent object. Setting DbContext.Configuration.LazyLoadingEnabled to true or false will have no impact on its behaviours.

If DbContext.Configuration.ProxyCreationEnabled is set to true, child objects will be loaded automatically, and DbContext.Configuration.LazyLoadingEnabled value will control when child objects are loaded.
Read More »

Thứ Hai, 14 tháng 3, 2016

Sửa lỗi update-database code first "there is already an object named"

update-database -verbose doesn't work because your model has been changed after your data table already existed.
First, make sure there are no changes to the UserProfile class. Then, run:
Add-Migration InitialMigrations -IgnoreChanges
This should generate a blank "InitialMigration" file. Now, add any desired changes to the UserProfile class. Once changes are added, run the update command again:
update-database -verbose
Now the automatic migration will be applied and the table will be altered with your changes
Read More »

Thứ Hai, 15 tháng 2, 2016

Resolved: configuration system failed to initialize

Obviously, the solution is to either repair or simply delete the user.config file, but we have to find it before we can do that. I won't get into repairing, since there's no simple way that I know of to do this. In most cases, deleting the user's application settings, while inconvenient, is not the end of the world, so long as the user is given fair warning that this is about to happen. You're free to take other measures, of course.

It turns out, the path to the user.config file was in the exception all along! But, it's sneakily hidden inside an InnerException, and maybe this is why it eluded me at first. So, allow me to present a block of code that will basically handle this occurrence in a universal manner. You should place this block somewhere near the beginning of your application startup, before any call to Settings is made:

try
        {
            ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.PerUserRoamingAndLocal);
        }
        catch (ConfigurationErrorsException ex)
        {
            string filename = string.Empty;
            if (!string.IsNullOrEmpty(ex.Filename))
            {
                filename = ex.Filename;
            }
            else
            {
                var innerEx = ex.InnerException as ConfigurationErrorsException;
                if (innerEx != null && !string.IsNullOrEmpty(innerEx.Filename))
                {
                    filename = innerEx.Filename;
                }                   
            }

            if (!string.IsNullOrEmpty(filename))
            {
                if (System.IO.File.Exists(filename))
                {
                    var fileInfo = new System.IO.FileInfo(filename);
                    var watcher
                         = new System.IO.FileSystemWatcher(fileInfo.Directory.FullName, fileInfo.Name);
                    System.IO.File.Delete(filename);
                    isReset = true;
                    if (System.IO.File.Exists(filename))
                    {
                        watcher.WaitForChanged(System.IO.WatcherChangeTypes.Deleted);
                    }
                }
            }
        }

ConfigurationErrorsException is the correct exception to throw in the situation you describe. An earlier version of the MSDN documentation for ConfigurationErrorsException makes more sense.
The earlier MSDN summary and remarks are:
  • The exception that is thrown when a configuration-system error has occurred.
  • The ConfigurationErrorsException exception is thrown when any error occurs while configuration information is being read or written.
Since CLR 2.0, the .NET Framework offers an extensive configuration module in System.Configuration. It differentiates between program and user settings:
TypeFileLocationOccurrenceUsage/Administration
Applicationapp.configProgram Folder1 per installationVisual Studio Project Properties: Settings
Useruser.configUser Profile Folder1 per userDerivation of ApplicationSettingsBase
The usage scenario determines which type of setting to choose:
Criterion/RequirementApplication SettingUser Setting
Setting is the same for all users (e.g., database connection)x
Setting can vary per user (e.g., theme)x
Temporary/local setting (e.g., location and size of a window)x
Storage of user input or selection (e.g., text alignment)x
Necessity to store settings fine grained (e.g., per plug-in)x

Control over the user settings is gained through inheriting from the class ApplicationSettingsBase. A single setting value can be defined via a property and a property attribute. The methods Reload()Reset()Save(), and Upgrade() determine the runtime behavior. The following illustration shows the data flow of the .NET user configuration:
User Settings Data Flow
The 'Default Value' is defined through the property attribute DefaultSettingValueAttribute. The value 'Init Value' is controlled by the .NET Framework. Access to the value of 'Session Value' occurs through the property which is marked with the UserScopedSettingAttribute, which in turn usesApplicationSettingsBase.Item.
The methods Reload() and Reset() support freshly loading all settings and setting them back to their 'Default Values, respectively.
When performing the first Save(), all user settings get stored in the XML file user.config. With every following program launch, the .NET Framework automatically loads them again (action Start). Where that configuration file will be located is influenced by several factors:
  • Profile Directory: The local or roaming profile directory (e.g., C:\Documents and Settings\MyName)
  • Company Name: The value of the AssemblyCompanyAttribute in AssemblyInfo.cs
  • App Name: The value of the AssemblyProductAttribute in AssemlyInfo.cs
  • Evidence Type and Evidence Hash: Information derived from the app domain evidence
  • Version: The value of the AssemblyVersionAttribute in AssemblyInfo.cs
If any of these factors change, the user settings will be stored (and looked for) in a different folder. The methodUpgrade() offers some support for migrating user settings from previous versions. Care should be taken, however, when changing either the company or the application name, as these changes will prevent future upgrades.

Read More »

Thứ Tư, 2 tháng 12, 2015

Factory method

Static Factory
Is a class with a Static Method to product various sub types of Product.
Static Factory
Simple Factory
Is a class that can produce various sub types of Product. (It is better than the Static Factory. When new types are added the base Product class does not need to be changed only the Simple Factory Class)
Simple Factoryt
Factory Method
Contains one method to produce one type of product related to its type. (It is better than a Simple Factory because the type is deferred to a sub-class.)
Factory Method
Abstract Factory
Produces a Family of Types that are related. It is noticeably different than a Factory Method as it has more than one method of types it produces. (This is complicated refer to next diagram for better real-life example).
Abstract Factory
Example From The .NET Framework
DbFactoriesProvider is a Simple Factory as it has no sub-types. The DbFactoryProvider is an abstract factory as it can create various related database objects such as connection and command objects.
Abstract Factory From .NET Framework
Read More »

Thứ Sáu, 27 tháng 11, 2015

Generic Repository in ASPNET5

In this post, I am explaining generic repository pattern using EF7. The Repository Pattern is a common construct to avoid duplication of data access logic throughout our application. The purpose of the repository is to hide the details of accessing the data. We can easily query the repository for data objects, without having to know how to provide things like a connection string. The Repository pattern adds a layer between the data and domain layers of an application. It also makes the data access parts of an application better testable.
Here is the initial version of repository interface.
1 public interface IEmployeeRepository
2 {
3     Task<Employee> Get(Guid? id);
4     Task Save(Employee employee);
5     Task Delete(Employee employee);
6     Task Update(Employee employee);
7     Task<IEnumerable<Employee>> FindAll();
8 }
It is specific to Employee class, respository contains CRUD operations. And here is the implementation ofEmployeeRepository class with DbContext.
 1 public class EmployeeRepository : IEmployeeRepository
 2 {
 3     private EmployeeContext _employeeContext;
 4     public EmployeeRepository()
 5     {
 6         _employeeContext = new EmployeeContext();
 7     }
 8     public async Task<Employee> Get(Guid? id)
 9     {
10         return await _employeeContext.Employees.FirstOrDefaultAsync(x => x.Id == id);
11     }
12     
13     public async Task Save(Employee employee)
14     {
15         _employeeContext.Employees.Add(employee);
16         await _employeeContext.SaveChangesAsync();
17     }
18     
19     public async Task Delete(Employee employee)
20     {
21         _employeeContext.Employees.Remove(employee);
22         await _employeeContext.SaveChangesAsync();
23     }
24     
25     public async Task Update(Employee employee)
26     {
27         _employeeContext.Employees.Update(employee);
28         await _employeeContext.SaveChangesAsync();
29     }
30     
31     public async Task<IEnumerable<Employee>> FindAll()
32     {
33         return await _employeeContext.Employees.ToListAsync();
34     }
35 }
And here is the Employee context object.
 1 public class EmployeeContext : DbContext
 2 {
 3     private static bool _created = false;
 4 
 5     public EmployeeContext()
 6     {
 7         if (!_created)
 8         {
 9             Database.EnsureCreated();
10             _created = true;
11         }
12     }
13     
14     public DbSet<Employee> Employees { get; set; }
15     protected override void OnConfiguring(EntityOptionsBuilder optionsBuilder)
16     {
17         optionsBuilder.UseInMemoryStore();
18     }
19 }
There are two problems with current EmployeeRepository implementation. First one it is using one model class, Employee, if you have multiple model classes, you need to duplicate lot of code. Second is it is not testable. The first problem you can fix by make it generic. And the second problem you can resolve by injecting the context object. Here is the generic repository interface.
1 public interface IGenericRepository<T> where T: class, IEntity, new()
2 {
3     Task<T> Get(Guid? id);
4     Task Save(T employee);
5     Task Delete(T employee);
6     Task Update(T employee);
7     Task<IEnumerable<T>> FindAll();
8 }
The IEntity interface contains only one property, Id.
1 public interface IEntity
2 {
3     Guid Id { get; set; }
4 }
And here is the implementation of GenericRepository class.
 1 public class GenericRepository<T> : IGenericRepository<T> where T: class, IEntity, new()
 2 {
 3     private DbContext _dbContext;
 4     public GenericRepository(DbContext dbContext)
 5     {
 6         _dbContext = dbContext;
 7     }
 8 
 9     public async Task Delete(T employee)
10     {
11         _dbContext.Set<T>().Remove(employee);
12         await _dbContext.SaveChangesAsync();
13     }
14 
15     public async Task<IEnumerable<T>> FindAll()
16     {
17         return await _dbContext.Set<T>().ToListAsync();
18     }
19 
20     public async Task<T> Get(Guid? id)
21     {
22         return await _dbContext.Set<T>().FirstOrDefaultAsync(x => x.Id == id);
23     }
24 
25     public async Task Save(T employee)
26     {
27         _dbContext.Set<T>().Add(employee);
28         await _dbContext.SaveChangesAsync();
29     }
30 
31     public async Task Update(T employee)
32     {
33         _dbContext.Set<T>().Update(employee);
34         await _dbContext.SaveChangesAsync();
35     }
36 }
In this implementation, one more problem exists, in the DbContext implementation, you need the reference ofEmployee model. You can make it DbContext also generic using Reflection.
 1 public class GenericDbContext : DbContext
 2 {
 3     private static bool _created = false;
 4     public GenericDbContext()
 5     {
 6         if (!_created)
 7         {
 8             Database.EnsureCreated();
 9             _created = true;
10         }
11     }
12     protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
13     {
14         optionsBuilder.UseInMemoryDatabase(true);
15     }
16     protected override void OnModelCreating(ModelBuilder modelBuilder)
17     {
18         var types = Assembly.GetExecutingAssembly().GetTypes()
19             .Where(type => typeof(IEntity).IsAssignableFrom(type) && type.IsClass);
20         var method = typeof(ModelBuilder).GetMethods().First(m => m.Name == "Entity"
21             && m.IsGenericMethodDefinition
22             && m.GetParameters().Length == 0);
23         foreach (var type in types)
24         {
25             method = method.MakeGenericMethod(type);
26             method.Invoke(modelBuilder, null);
27         }
28 
29         base.OnModelCreating(modelBuilder);
30     }
31 }
In OnModelCreating method, all the types which implements IEntity interface are added to the DbContextusing Entity() method. This method is invoked dynamically using reflection. In ASP.NET 5, you can inject the repository and the context using inbuilt dependency injection feature.
1 public void ConfigureServices(IServiceCollection services)
2 {
3     services.AddMvc();
4     services.AddScoped<DbContext, GenericDbContext>();
5     services.AddScoped<IGenericRepository<Employee>, GenericRepository<Employee>>();
6 }
And here are the unit tests for create.
Happy programming! Smile | :)

Source: http://www.codeproject.com/Articles/1035618/Generic-Repository-in-ASPNET
Read More »