Skip to content
August 9, 2012 / chadmeyercodez

Entity Framework Code First when Model Exists

I recently implemented Entity Framework 4.3 into a production project. The challenge was I wanted to use the code first ideas and I didn’t want to generate a bunch of edmx files that had a lot of designer code that no one cares to understand. A couple of searches lead me to the Entity Framework Power Tools which is currently in Beta 2. This little package will allow you to reverse engineer databases into code first POCO classes.

The first time that I set up Power Tools for our project, I wanted to customize the reverse engineer code first templates. I wanted to do this to set up some coding standards including pascal casing properties and pluralizing collections. Some of the database tables also have an underscore in the table and column names which I do not want in my OR/M. In order to customize the templates open the solution that you want to use Entity Framework with, right click on the project you want to store your POCO classes, select the Entity Framework option and then Customize Reverse Engineer Templates. This will create a folder in that project called ReverseEngineerCodeFirst. Underneath this folder are three files: one for the context, one for the entity and one for the mapping.

This is a great start, you can change anything about the T4 template. I wanted to write some more custom code in order to remove underscores and pascal case some property names. This is where challenge 2 comes in. The T4 templates include a file called “EF.Utility.CS.ttinclude”. Finding this file was a chore, I finally found it was being referenced from C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\Extensions\Microsoft\Entity Framework Tools\Templates\Includes. Your path might be slightly different depending on where you installed Visual Studio. Here are a couple of methods that I created to help with code standards.

Pluralize

public string Pluralize(string word) {
    var p = System.Data.Entity.Design.PluralizationServices.PluralizationService.CreateService(new CultureInfo("en-US"));
    return p.Pluralize(word);
}

PascalCaseProperty

/// <summary>
/// Returns the passed in identifier with the first letter changed to uppercase
/// </summary>
public string PascalCaseProperty(string identifier) {
    if (String.IsNullOrEmpty(identifier)) {
        return identifier;
    }

    string returnString = identifier;

    // If there is an underscore anywhere within the identifier 
    // strip them out upper casing the first letter 
    if (identifier.IndexOf("_") >= 0) {
        returnString = string.Empty;
        string[] propertySplit = identifier.Split('_');

        if (propertySplit != null) {
            for (int i = 0; i > propertySplit.Length; i++) {
                if (!string.IsNullOrEmpty(propertySplit[i])) {
                    returnString += propertySplit[i].Substring(0, 1).ToString(CultureInfo.InvariantCulture).ToUpperInvariant();
                    returnString += propertySplit[i].Substring(1).ToLowerInvariant();
                }
            }
        }
    }
    else {
        returnString = identifier.Substring(0, 1).ToString(CultureInfo.InvariantCulture).ToUpperInvariant();
        returnString += identifier.Substring(1).ToLowerInvariant();
    }

    // Find out if the last two letters are ID
    string returnStringID = returnString.Substring(returnString.Length - 2);

    if (returnStringID.ToLower() == "id") {
        returnString = returnString.Substring(0, returnString.Length - 2) + "ID";
    }


    return returnString;
}

I created these methods in the c# ttinclude file. You can reference the code from the context.tt, entity.tt and mapping.tt with the following

Pascal Casing

<#= code.PascalCaseProperty(efHost.EntityType.Name) #>

Pluralize

<#= code.Pluralize(code.PascalCaseProperty(code.Escape(navProperty))) #>

Once you have your context, entity and mapping the way you want it, just go to the project and right click, hit Entity Framework, Reverse Engineer Code First. This will allow you to specify a database connection and the database you want to scaffold out. It might take a few minutes, depending on how many tables you have in the database.

Advertisements
July 14, 2012 / chadmeyercodez

Repository Pattern with Entity Framework

I recently started an initiative at work to move to one O/RM. Traditionally we have created our own custom way to access our data. It has worked for our needs but with the addition of Entity Framework 5.0, now seems like a good time to move to a technology that is backed by groups that maintain and enhance the technology. We also use the Repository Pattern in our architecture. It makes for a nice abstraction between data access and business logic along with making it easy to mock up in unit testing our controllers.

The example I will be talking about is in a git repo. I generated the Northwind database from Microsoft. I used the Entity Framework Power Tools in order to reverse engineer the database to code first POCO classes.

A BaseRepository is created to hold the DBContext and to handle disposing of the context. The thought process is this will allow change tracking to take care of changes in the entities and by default handle transactions.

public interface IBaseRepository {
    void Dispose();
    List RepositoryDatabaseErrors { get; set; }
}

public class BaseRepository : IBaseRepository, IDisposable {

    #region Constructor
    public BaseRepository() {
        this._databaseErrors = new List();
    }
    #endregion Constructor

    #region Properties
    private List _databaseErrors;
    public List RepositoryDatabaseErrors {
        get {
            if (_databaseErrors == null) {
                _databaseErrors = new List();
            }
            return _databaseErrors;
       }
       set { this._databaseErrors = value; }
    }

    private Web.Entity.NorthwindContext _dbContext = null;
    public Web.Entity.NorthwindContext DBContext {
        get {
            if (this._dbContext == null) {
                this._dbContext = new Entity.NorthwindContext();
            }
            return this._dbContext;
        }
    }
    #endregion Properties

    #region Dispose Methods

    ~BaseRepository() {
        Dispose(false);
    }

    public void Dispose() {
        Dispose(true);
        GC.SuppressFinalize(this);
    }

    protected virtual void Dispose(bool disposing) {
        if (this._dbContext != null) {
            this._dbContext.Dispose();
            this._dbContext = null;
        }
    }
    #endregion Dispose Methods
}

With the BaseRepository written, all other respoitories will inherit from the BaseRepository. Lets move on to the controller. For this example there is only one, HomeController. A Repository is created for the HomeController that will hold all the data access methods the controller actions need. It will consist of two methods, one to find all the employees in the northwind database and one to save the db context.

    #region Repository
    public interface IHomeRepository : IBaseRepository {
        List<Employee> FindEmployees();
        bool Save();
    }

    public class HomeRepository : BaseRepository, IHomeRepository {
        public List<Employee> FindEmployees() {
            return (from e in base.DBContext.Employees
                    select e).ToList();
        }

        public bool Save() {
            try {
                base.DBContext.SaveChanges();
                return true;
            }
            catch (System.Data.Entity.Validation.DbEntityValidationException ex) {
                foreach (DbEntityValidationResult result in ex.EntityValidationErrors) {
                    base.RepositoryDatabaseErrors.Add(result);
                }
                return false;
            }
        }
    }
    #endregion Repository

The controller will have a property called Repository so the controller actions can interact with the database. In the example, a list of employees is pulled from the database then all employees are updated with a first name and last name change. The purpose is to show that the entities dont need to be re attached to the data context. The DBContext change tracker will keep track of the changes that happen. When SaveChanges is called on the DBContext it will be able to see all changes that need to happen. This is the reason why the DBContext is opened on the base. If we were to new up a DBContext every time we call a method to the database, then we would have to attach the changed entities or find another way to save them. This way allows for all alterations to happen in the business logic and the database access happen in the repository.

    public class HomeController : BaseController {

        #region Properties
        public IHomeRepository Repository { get; set; }
        #endregion Properties

        #region Constructor
        public HomeController() {
            this.Repository = new HomeRepository();
        }
        #endregion Constructor

        public ActionResult Index() {

            List<Employee> employees = this.Repository.FindEmployees();

            // Updates the employees name, this will show that the change tracker of the DBContext 
            // picks up the changes so there is no need to attach them to the context
            employees.ForEach(delegate(Employee currentEmployee) {
                currentEmployee.FirstName = "Repository";
                currentEmployee.LastName = "EntityFramework";
            });

            if (!this.Repository.Save()) {
                foreach (DbEntityValidationResult result in this.Repository.RepositoryDatabaseErrors) {
                    foreach (DbValidationError error in result.ValidationErrors) {
                        this.ModelState.AddModelError("", error.ErrorMessage);
                    }
                }
            }

            return View();
        }

        #region Overrides
        protected override void Dispose(bool disposing) {
            // This is important. We must dispose the repository here in each controller
            this.Repository.Dispose();

            base.Dispose(disposing);
        }
        #endregion Overrides

    }

I really enjoy Entity Framework as an O/RM. One thing I would like to try to change is to move the dispose of the repository to the base controller so the dev does not have to remember to call dispose on each new controller. I will post an update when we figure something out.

July 6, 2012 / chadmeyercodez

Redis Session State Provider for ASP.NET

Redis is an open source, advanced key-value store. It is often referred to as a data structure server since keys can contain strings, hashes, lists, sets and sorted sets. This makes it a perfect solution for session state caching. With it having expiration built in, there is no external jobs that need to run to clean up old sessions.

Using the MSDN article for a custom session-state store provider as a template, I created a way to interact with Redis for all session data. I have done some testing on the solution but not extensive yet. I hope to get it implemented into Fellowship One within the next couple of days which uses session state database currently for some real testing. I created the redis solution as a github repo.

Microsoft Open Tech has created a Windows supported Redis solution on github which is what I used to test the redis based session state provider. You can compile the solutions into executables to run the redis server and other redis monitoring tools.

to implement the solution, take the RedisSessionProvider.cs file from the SessionProvider folder and put this into your project. Next we have to tell our application to use a custom session state provider by inserting the following into the web.config.

<sessionState mode="Custom" customProvider="RedisSessionStateProvider" cookieless="false" timeout="1">
    <providers>
        <add name="RedisSessionStateProvider"
             type="RedisProvider.SessionProvider.CustomServiceProvider"
             server="localhost"
             port="6379"
             password=""
             writeExceptionsToEventLog="false">
    </providers>
</sessionState>

The values presented currently are the default redis values. These will probably change as you move your solution to production. The timeout is set to 1 currently so I could prove that session items were really dropping off the list. Also note that you can change the namespace of the custom service provider. If you do, just remember to change the type in the web.config to that namespace.

TODO List:

  • It is recommended that exceptions from session to captured in the application event log. This has yet to be implemented
  • I want to compiled this solution to a single dll so enhancements will be simplified. Instead of copying files and code, a quick reference to the dll will move session to redis.
August 19, 2011 / chadmeyercodez

iOS Multi-select Table Cells

I created a way to select multiple table cells in a UITableView by making a custom UITableView along with custom UITableViewCell. I will go through some of the main features of this. You can get the complete code on github.

On initialization of the table view, a notification is created to listen for the selecting of table cells. We turn off the ability for the table to allow selection. We will handle that in the table cell itself.

- (id)initWithFrame:(CGRect)frame style:(UITableViewStyle)aStyle notification:(NSString *)notification {
    if ((self = [super initWithFrame:frame style:aStyle])) {
        // Initialization code
        self.allowsSelection = NO;

		// Create a notification to select table cells
		self.selectedTableCells = [[NSMutableArray alloc] init];
        [[NSNotificationCenter defaultCenter] addObserver: self
                                                 selector: @selector(notificationChangeSelectedCells:)
                                                     name: [NSString stringWithFormat:@"FTPUITableView_%@", notification]
                                                   object:nil];
    }
    return self;
}

The method for firing the notification first determines if the table is set up to handle multi select. If it is then it goes through some logic to determine if the cell is being asked to be selected or unselected. It will then draw the cell the way it needs to be presented.

- (void) notificationChangeSelectedCells: (NSNotification *) notification {
	
	FTPUIMultiSelectTableViewCell *notificationTableCell = (FTPUIMultiSelectTableViewCell *)[notification object];
	
	if (self.isMultiSelect) {
		
		// If the object is not a check in table cell, we are not interested in it
		if ([[notification object] isKindOfClass:[FTPUIMultiSelectTableViewCell class]]) {
			
			if ([self isTableCellSelected:[notificationTableCell rowNumber]]) {
				[self.selectedTableCells removeObject:[NSNumber numberWithInteger:[notificationTableCell rowNumber]]];
			}
			else {
				[self.selectedTableCells addObject:[NSNumber numberWithInteger:[notificationTableCell rowNumber]]];
			}
			
			// Draw the cell
			[notificationTableCell drawCell:[self isTableCellSelected:[notificationTableCell rowNumber]]];
		}
	}
	else {
		// get all the visible cells to deselect one of the cells
		NSArray *visible = [self visibleCells];
		
		for (FTPUIMultiSelectTableViewCell *current in visible) {
			if (current.rowNumber != notificationTableCell.rowNumber) {
				current.isSelected = NO;
				[current drawCell:NO];
			}
			else {
				current.isSelected = YES;
				[current drawCell:YES];
			}

		}
	}
}

The table cell has a few methods to draw the cell for presentation. This can be customized however you want your cell to look. The first method sets the properties of the cell. All the properties are needed for the table view to properly analyze the state of the cell.

- (void) drawCell:(NSIndexPath *)indexPath withSectionRows:(NSInteger)sectionRows hasSelector:(BOOL)selector isSelected:(BOOL)selected {
	
    [self setHasSelector:selector];
	[self setRowNumber:[indexPath row]];
	[self setTotalRowsInSection:sectionRows];
	[self setIsSelected:selected];
	[self drawCell:selected];
}


- (void) drawCell: (BOOL)isHighlight {
    
	// If the cell has a selector, populate the selector view
	if (self.hasSelector) {
		if (isHighlight) {
            UIImage *table_row_select = [UIImage imageNamed:@"icon_check_square.gif"];
            ((UIImageView *)self.imageView).image = [self scale:table_row_select toSize:CGSizeMake(20, 20)];
            [self.contentView setBackgroundColor:self.highlightedColor];
		}
		else {
            UIImage *hollow_image = [UIImage imageNamed:@"select_hollow.png"];
            ((UIImageView *)self.imageView).image = [self scale:hollow_image toSize:CGSizeMake(20, 20)];
            [self.contentView setBackgroundColor:self.unhighlightedColor];
		}
	}
	
	[self changeLabelColors:isHighlight];
}

- (void) changeLabelColors:(BOOL) selected {

	// Find all labels that are part of the content view
	for (UIView *current in [self.contentView subviews]) {
		
		if ([current isKindOfClass:[UILabel class]]) {
			UILabel *currentLabel = (UILabel *)current;
			if(selected) {
				[currentLabel setTextColor:[UIColor whiteColor]];
			}
			else {
				[currentLabel setTextColor:[UIColor blackColor]];
			}
		}
	}
}

When the cell is created in the table view delegate method of cellForRowAtIndexPath the cell is given the notification name as well. Then the cell is drawn given the parameter values

    NSString *arrayText = [tableResults objectAtIndex:[indexPath row]];

    static NSString *CellIdentifier = @"Cell";
    FTPUIMultiSelectTableViewCell *cell = (FTPUIMultiSelectTableViewCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];

    if (cell == nil) {
        cell = [[[FTPUIMultiSelectTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];

		cell.selectionStyle = UITableViewCellSelectionStyleNone;

		// Notification name
		cell.notificationName = @"multi_select";
	}

	// Creates the cell with all the necessary variables to set up custom UX presentation
	[cell drawCell:indexPath
       withSectionRows:[tableView numberOfRowsInSection:[indexPath section]]
           hasSelector:YES
            isSelected:[table isTableCellSelected:[indexPath row]]];

    return cell;

The touch event of the table cell fires of the notification

- (void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
    [[NSNotificationCenter defaultCenter] postNotificationName:[NSString stringWithFormat:@"%@%@", NotificationPrefix, [self notificationName]] object:self];
}

This shows some of the features of how to do multi select in a custom UITableView. I recommend going to iOS-multi-select, grabbing the actual project and mess around with it. I would definitely be interested in any comments or concerns.