Archive

Posts Tagged ‘EF’

Executing Scripts during EF Code First Migrations

September 20th, 2012 1 comment

I’ve spent the last two days converting a training application from Model First to Code first and enabling Migrations.  I knew I wanted to use the Migrations functionality on a new project that I’m starting in a few weeks and converting an existing application seemed the best way to really get my hands dirty.  I must say, I love the possibilities that this new feature set opens up, especially around just working within the development team.  No more “Oh, yea, I updated the database last night, I forgot to check in the script, I’ll send it right away”.  The development code will just update itself.  Glorious.

One issue I ran into is the ability to execute an arbitrary script as part of a migration.  I wanted to do this so that the initial configuration would also create the asp.net membership provider objects and the Sql Server ELMAH objects that are used behind the scenes.  One less thing to think about for a new developer or pushing into a new Dev/QA environment.

After much googling, it seemed that there is no good way to accomplish this task.  The migrations code exposes a Sql() command that will execute one sql statement, and you can do the same thing in the Configuration.Seed function by accessing the context directly.  Either way, not as clean as just giving an entire script over to Sql Server for execution.

I had a fully executable script, so instead of trying to parse it out manually as almost every post I found said to do, I worked around it by using this code:

I embedded the two scripts into my model assembly and then just split them apart to execute each statement one at a time.   I had to use “GO\r\n” due to the fact that the aspnet objects actually use GOTO in them.

It feels a little hackish, but it gets the job done and simplifies the initial creation as well as the maintenance of these objects.   This gets us back to, when a new developer starts.

Dev: “How do I set up the database”
Everyone: “Run the App”

Glorious.

 

Categories: Coding Tags: ,

Entity Framework Objects with Proxies, MVC4, and Telerik Grids.

August 8th, 2012 No comments

I’m currently working on a side project that is using MVC4 and EF5. Some of the EF objects have bi-directional navigation on them due to how they’ll end up being rendered.

I was trying to wire up a Telerik MVC grid for data entry and received this error on the grid select:“A circular reference was detected while serializing an object of type ‘System.Data.Entity.DynamicProxies.CourseType”.

After some googling, the easiest answer I found was to disable proxy generation. This was fine as I wasn’t using lazy loading. Once I did that, I started getting this exception: “The RelationshipManager object could not be serialized. This type of object cannot be serialized when the RelationshipManager belongs to an entity object that does not implement IEntityWithRelationships.”. The easy answer didn’t work.

At first I tried to set up the Json serialization settings of the global formatter since MVC4 uses JSON.Net by default.

That did not solve the problem.

I then found a code sample on Telerik’s site that accomplished the goal, but it seemed overly complex (it may have just been the only way to solve it in mvc3). Based on that code sample, and using JSON.Net, this is what I came up with as a final solution:

Update: For this to work, Proxy generation still needs to be disabled. I didn’t make that clear in the original text.

Categories: Coding Tags: ,

Entity Framework Performance Tip – Did your object really change?

May 29th, 2012 No comments

During the performance testing of one of our batch jobs, we discovered that we were always sending objects back to the database; whether they had actually changed or not.  When you’re processing 100,000 objects, this can be quite the performance hit.  What I discovered is that almost half of the objects didn’t change, but their entity state was set as modified.  After some additional debugging, I narrowed it down to this code in the EF designer.cs:


set
{
OnNameChanging(value);
ReportPropertyChanging("Name");
_Name = StructuralObject.SetValidValue(value, true);
ReportPropertyChanged("Name");
OnNameChanged();
}

The setter of every property was marking the object as Modified, whether the value actually changed or not!

I could have solved the problem in the batch job by checking the values before I set them, but I opted to solve it globally (we have about 30 batch jobs) by modifying the EF generated code instead.  After all, the object should be able to correctly keep track of it’s own state.   This first required me to switch to using a T4 template.

Switching to T4 Templates

 

The first step is to remove the default classes generated by Entity Framework by removing the EntityModelCodeGenerator from the Edmx file.  On the left is the before window, and the right is after.

Edmx Property comparison

 

The next step is to add the T4 template to your project.  Right Click on your project -> Add New Item -> Select ADO.Net EntityObject Generator

Add New T4 Template Dialog

 

With the new t4 template, make sure that the Custom Tool property is set to “TextTemplatingFileGenerator“.  Right Click the template and select Run Custom Tool to generate the EF Code.

 

Modifying the template*

 

Now that we’re using the T4 template to generate our entity code, we can go in and modify the way property setters work.  The first place we’re going to look for is on the setting of primitive types.   Look for the function “WritePrimitiveTypeProperty”.   Once you find it, you’ll see the template code for generating the primative setter.

 

Code snip-it  of the T4 template for generating the primitive setter

In the default template, the primary key fields had logic to only mark it as changed if the value was different.  In the updated template.  you’ll notice that I just commented out the check to see if it was the primary key.  This way that logic applies to all primitive fields.

The second change is to update the function “WriteComplexTypeProperty“.  This change is more straight forward as there was no pre-existing logic in the setter.  The final result is this:

Complex Property Setter in T4 Template
This code can be copied from Gist

we’ve now modified the template to make our objects a little smarter about marking themselves as modified.  Right click on the T4 template file in solution explorer and run the custom tool again, and voila!.


set
{
if (_Name != value)
{
OnNameChanging(value);
ReportPropertyChanging("Name");
_Name = StructuralObject.SetValidValue(value, true);
ReportPropertyChanged("Name");
OnNameChanged();
}
}

In future blog posts I’ll talk about the other changes we’ve made to the default behavior that might be useful to others.

What are the ways you wish EF operated differently that could be accomplished by modifying the T4 templates?

 

*These steps are specific to EF4.  I have not upgraded to EF5 yet, and have not gone through the exercise to modify the updated T4 template.

Categories: Coding Tags: , , ,

Entity Framework – Dictionary / Resource based Pre-Compiled Views

May 25th, 2012 No comments

Our entity model is big.  We have about 120 physical tables and approximately 700 entity views, and it’s still growing.  To combat cold startup time, we use EdmGen to pre-compile the entity views and it has decreased the start-up time of the application by a very noticeable amount.

A while back we started noticing that on query intensive screens, the look-up of the views in the entity views class was showing up in the profiling.  This seemed very odd.  However, once you go look at the view file, it make sense.


protected override System.Collections.Generic.KeyValuePair<string,string> GetViewAt(int index)
{
if ((index == 0))
{
return GetView0();
}
.....[snip].....
if ((index == 650))
{
return GetView650();
}
}

If you have to bounce through 600 if statements to find the one you’re looking for, that might show up on a profiler, especially if 5 queries in a row are at the bottom.   While looking for a potential solution to this problem I found the following blog post describing a way to use a dictionary instead of the standard file (I’m the Ed in the comments section).   It was advantageous that I found that post, because when I did a quick analysis of our entity DLL, I discovered that we were also very close to hitting the issue Jamie was solving.

The premise is that you parse the EdmGen view file and rip out all of the view strings and store them in a resource file.  That binary resource file does not count against your string limit and helps decrease your deployment size as well.  On top of that, you can read in that resource file and store them in a dictionary, so that when Entity Framework asks for a view, it’s an O(1) operation instead of O(n).


protected override System.Collections.Generic.KeyValuePair GetViewAt(int index)
{
System.Collections.Generic.KeyValuePair toRetrieveKVP = rsxDictionary[index];
return toRetrieveKVP;
}

We modified Jamie’s solution to use in memory compilation instead of regex parsing as we found that EdmGen had too many variations and the process kept breaking down for us.


var codeProvider = new CSharpCodeProvider();
var inMemoryCodeCompiler = codeProvider.CreateCompiler();
var parameters = new CompilerParameters();
parameters.ReferencedAssemblies.Add("System.Data.Entity.dll");
parameters.GenerateInMemory = true;
CompilerResults results = inMemoryCodeCompiler.CompileAssemblyFromFile(parameters, csFile);

The full source code can be found on my GitHub page.

Once we had the MakeResX program working to our satisfaction, it was just a matter of wiring it up into our process, which now looks like this:

  1. Modify EDMX
  2. Build to generate csdl, sdl, and msl.
  3. Run this bat file
    
    set buildDir=..\..\..\..\Source\Domain\Model\bin\Debug\
    "%windir%\Microsoft.NET\Framework\v4.0.30319\EdmGen.exe" /nologo /language:CSharp /mode:ViewGeneration "/inssdl:%buildDir%DomainModel.ssdl" "/incsdl:%buildDir%DomainModel.csdl" "/inmsl:%buildDir%DomainModel.msl" "/outviews:%buildDir%DomainModelEntityManager.Views.cs"
    set outDir=..\..\..\..\Source\Domain\Model\EntityView\
    ..\..\Binaries\MakeRes.exe %buildDir%\DomainModelEntityManager.Views.cs %outDir% DomainModelEntityViews
    
    
  4. Build with the new dictionary and resource file
    EntityViews files included in the solution

If someone forgets to run step 3, the application won’t start.  Entity Framework will throw a hash violation on the strings.  As a result, outdated views is not something you need to worry will silently make it into QA.

 

Categories: Coding Tags: , ,