HiveBrain v1.2.0
Get Started
← Back to all entries
patterncsharpMinor

Entity Framework 6.0.2 - Performance of Auditable Change Tracking Part 1 of 2

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
auditabletrackingpartperformanceframeworkchangeentity

Problem

This is Part 1 of a question about performance and general best practices. Part 2 is located here. The body of the messages are the same to illustrate their similarity, the difference is the code provided. This one provides the data the text template utilizes, the other provides the logic to generate the code. The focus isn't so much on the template, but the pattern of managing a database that tracks changes across potentially multiple domains.

Another thing I decided I'll be adding: the templates will construct the basic outline of the dialogs through WPF for me. In the case of searching for items within the database, I've already used the data on the entities to generate query builders:

var recipeQuery = new RecipeQueryData(user);
recipeQuery.CreateIngredientsQueryData();
recipeQuery.IngredientsData.CreateItemQueryData();
recipeQuery.IngredientsData.ItemData.NameCriteria = "t";
recipeQuery.IngredientsData.ItemData.SearchNameType = StringSearchType.Contains;
var recipesWithT2 = RecipeQueryData.ConstructQuery(recipeQuery, fcasCtx.Recipes);


Compared with:

var recipesWithT =
    (from recipe in fcasCtx.Recipes
     from ingredient in recipe.Ingredients
     where ingredient.Item.Name.Contains(criteria)
     select recipe).Distinct();

Console.WriteLine(recipesWithT.ToString() == recipesWithT2.ToString());


Yields true. While by itself isn't much, it's interesting that I'll be able to enable a user to have a fairly powerful search tool by specifying nested conditions.

I've uploaded a small example which demonstrates the template's use. It's changed quite a lot since the code posted and edited by lol.upvote. It automatically generates the files and folders based off of the context namespace provided in EntityConstants.tt. To preserve space I've removed all binaries, so you might have to fix it in the package manager console when you load the solution.

I'm kind of new to the realm of Database authoring, so I wanted to get some feedback on

Solution

I'm not familiar with template coding but I could follow this script all along, except this one-liner:

public <# WriteLine(string.Format("{3}{0} {1} {{ get; {2}set; }}", string.Format("{0}{1}", property.Value.DataType, (nullableTypes.Contains(property.Value.DataType) && (property.Value.Requirements & ER_REQUIRED) != ER_REQUIRED) ? "?" : string.Empty), property.Key, ((property.Value.Requirements & ER_NOTTRACKED) == ER_NOTTRACKED) ? string.Empty : "protected ", targetEnt != null ? "virtual " : string.Empty));


Doesn't parse in my poor little fried brain. I couldn't figure out where the protected was going to end up.

I need to break it down to see what it does:

WriteLine(
    string.Format("{3}{0} {1} {{ get; {2}set; }}", 
        string.Format("{0}{1}", 
            property.Value.DataType, 
            (nullableTypes.Contains(property.Value.DataType) 
             && (property.Value.Requirements & ER_REQUIRED) != ER_REQUIRED) 
                ? "?" 
                : string.Empty), 
        property.Key, 
        ((property.Value.Requirements & ER_NOTTRACKED) == ER_NOTTRACKED) 
                ? string.Empty 
                : "protected ", 
        targetEnt != null 
                ? "virtual " 
                : string.Empty));


How about at least putting the arguments in order?

WriteLine(
    string.Format("{0}{1} {2} {{ get; {3}set; }}", 
        targetEnt != null 
                ? "virtual " 
                : string.Empty
        string.Format("{0}{1}", 
            property.Value.DataType, 
            (nullableTypes.Contains(property.Value.DataType) 
             && (property.Value.Requirements & ER_REQUIRED) != ER_REQUIRED) 
                ? "?" 
                : string.Empty), 
        property.Key, 
        ((property.Value.Requirements & ER_NOTTRACKED) == ER_NOTTRACKED) 
                ? string.Empty 
                : "protected "));


If it's possible, I'd try to break this into something like 3 lines, be it only for readability.

Minor annoyance, the resulting code seems to have mixed tabs and spaces:

I don't like the redundant this qualifier sprinkled everywhere, but the code is very consistent about it, so it's only down to personal preference here.

I find this is a very interesting approach, however it's also a very intrusive one: if I understand your code correctly, your entities are being so much more than the regular average POCO out there.

This breaks the Single Responsibility Principle. I believe a decorator would be less intrusive, and more focused - basically compose the functionality rather than inheriting it.

Code Snippets

public <# WriteLine(string.Format("{3}{0} {1} {{ get; {2}set; }}", string.Format("{0}{1}", property.Value.DataType, (nullableTypes.Contains(property.Value.DataType) && (property.Value.Requirements & ER_REQUIRED) != ER_REQUIRED) ? "?" : string.Empty), property.Key, ((property.Value.Requirements & ER_NOTTRACKED) == ER_NOTTRACKED) ? string.Empty : "protected ", targetEnt != null ? "virtual " : string.Empty));
WriteLine(
    string.Format("{3}{0} {1} {{ get; {2}set; }}", 
        string.Format("{0}{1}", 
            property.Value.DataType, 
            (nullableTypes.Contains(property.Value.DataType) 
             && (property.Value.Requirements & ER_REQUIRED) != ER_REQUIRED) 
                ? "?" 
                : string.Empty), 
        property.Key, 
        ((property.Value.Requirements & ER_NOTTRACKED) == ER_NOTTRACKED) 
                ? string.Empty 
                : "protected ", 
        targetEnt != null 
                ? "virtual " 
                : string.Empty));
WriteLine(
    string.Format("{0}{1} {2} {{ get; {3}set; }}", 
        targetEnt != null 
                ? "virtual " 
                : string.Empty
        string.Format("{0}{1}", 
            property.Value.DataType, 
            (nullableTypes.Contains(property.Value.DataType) 
             && (property.Value.Requirements & ER_REQUIRED) != ER_REQUIRED) 
                ? "?" 
                : string.Empty), 
        property.Key, 
        ((property.Value.Requirements & ER_NOTTRACKED) == ER_NOTTRACKED) 
                ? string.Empty 
                : "protected "));

Context

StackExchange Code Review Q#41796, answer score: 2

Revisions (0)

No revisions yet.