Sergey Maskalik

Sergey Maskalik's blog

Focusing on improving tiny bit every day

After I uninstalled Visual Studio 2012, the deployment package creation script that builds and publishes a project using MSBuild started throwing a lovely exception:

.csproj(795,3): error MSB4019: The imported project “C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v11.0\We bApplications\Microsoft.WebApplication.targets” was not found. Confirm that the path in the declaration is correct, and that the file exists on disk.

From the error, I can tell that MSBuild is using the wrong Visual Studio version. My first thought was to to tell MSBuild to use v12 to build target by adding a VisualStudioVersion environment variable /p:VisualStudioVersion=12.0 but that resulted in a new error that was a little more confusing:

C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v12.0\Web\Transform\Microsoft.Web.Publishing.AspNetCompileMerge.targets(132,5): error : Can’t find the valid AspnetMergePath

I guess something has changed, and indeed, after searching I found that that yes MSBuild now ships as a part of Visual Stuido.

So rather than having MSBuild shipped as a component of a .NET framework, it is now a stand alone package that comes with Visual Studio and each version corresponds to the Visual Studio version with it’s own toolsets. So the new MSBuild will be under:

On 32-bit machines they can be found in: C:\Program Files\MSBuild\12.0\bin

On 64-bit machines the 32-bit tools will be under: C:\Program Files (x86)\MSBuild\12.0\bin

So if you are building you project using C:\Windows\Microsoft.NET\Framework\v4.0.30319\msbuild.exe, without Visual Studio 2012 installed, it will no longer work, and you will need to switch your build tool to use a new msbuild 12.0 in C:\Program Files (x86)\MSBuild\12.0\Bin\MSBuild.exe.

That’s it, hopefully this post will save someone some time.

Detached objects, or objects that are created outside of Entity Framework(EF), don’t have automatic tracking enabled, and updating database from detached objects is not hard, but requires extra knowledge of EF. With this post I’d like to spell out different ways of doing it.

Before doing anything else, we must first check the state of an entity. If you are using Code First, an entity would be your POCO class that is mapped to the database table.

To get information about an entity in question, and it’s relation to the current DbContext, you call a DbContext.Entry<TEntity> method. It will return a DbEntityEntry<TEntity> object which can be used to check the state and perform additional actions on the entity.

When you create a new instance of a class outside of EF, it will have a detached state because context is not tracking that object.

var customer = new Customer();
var customerEntry = _context.Entry<T>(customer);
Debug.Write(customerEntry.State) // EntityState.Detached

If your object is in any state other than EntityState.Detached, that means EF knows about it and tracks it, so you don’t need to do anything else, DbContext.SaveChanges() would take care of persisting differences into the database.

When at first I was trying to update database from a detached object I thought that I can simply attach it and set it to be modified.

public override void Update(T entity)
{
	var entry = _context.Entry<T>(entity);

	if (entry.State == EntityState.Detached)
	{
		_context.Set<T>().Attach(entity);
		entry.State = EntityState.Modified;
	}
}

And that would work, but only if the object with the same key is not already present in the context. And if it does exist, you get a nice error:

An object with the same key already exists in the ObjectStateManager. The ObjectStateManager cannot track multiple objects with the same key.

So what do you do when an object is already being tracked by EF and you have a detached object, how do you merge them together?

Fortunately, EF does provide a way to update an existing object from a detached object. There are couple different ways you can do it, and it all depends on the context, and what you know about your object.

Here is the first way you can do it:

Querying Database First And Updating Tracked Object

using(var db = new StoreDbContext())
{
	var existingCart = db.Carts.Find(cartId);
	if(existingCart != null)
	{
		//entity is already in the context
		var attachedEntry = db.Entry(existingCart);
		attachedEntry.CurrentValues.SetValues(newCart);
	}
	else
	{
		//Since we don't have it in db, this is a simple add.
		db.Cart.Add(newCart);
	}
}

After querying a database and finding a record, we know that EF is already tracking the existing object. We then get an entry object of the tracked entity and call attachedEntry.CurrentValues.SetValues to update it with new values. This method works like an auto mapper and updates scalar properties from the passed in object. Also if the property values is different from the original, it sets the property state to be modified.

That works, but requires an extra database call to get an existing record. There is also a way to do that without an extra query.

Not Performing An Extra Database Call And Checking Local Context

There are times when you know for fact an entity is already in the database. An example would be when a database generated id of your object is not set to zero or default. In that situation you can save an extra call by querying the local context first. If an entity does exist in the local context you perform a similar update with attachedEntry.CurrentValues.SetValues, and if it does not exist, you can modify a state of your detached object to modified, which would attach the object and update the database.

For example, when I know that the cart id is not zero, that means it already exists in the database:

if(newCart.Id > 0) // Id already assigned, need to update.
{
	//We query local context first to see if it's there.
	var attachedEntity = db.Carts.Local.Find(newCart.Id);

	//We have it in the context, need to update.
	if (attachedEntity != null) {
		var attachedEntry = _context.Entry(attachedEntity);
		attachedEntry.CurrentValues.SetValues(newCart);
	}
	else
	{
		//If it's not found locally, we can attach it by setting state to modified.
		//This would result in a SQL update statement for all fields
		//when SaveChanges is called.
		var entry = db.Entry(newCart);
		entry.State = EntityState.Modified;
	}
}
else
{
	//This is a simple add since we don't have it in db.
	db.Cart.Add(newCart);
}

There is a small difference when you query the database first. EF knows which values have been modified an only those specific value. On the other hand, when you are blindly attaching modified entity, EF doesn’t know what fields have changes and performs an update on all fields.

It Works, But Not Fully…

When you call CurrentValues.SetValues(newCart) it will update all scalar properties on your newCart object and set them to modified. However, navigation properties would not get the same respect. As of today EF does not support of full object graph merging, and leaves that for you to manage on your own. So if you have newCart.Customer navigational property it would not get updated. It’s the second most requested feature for EF at the moment, so I think they would add it in the future release.

So for now you have to manually call SetValues on all your navigational properties in order for them to be updated. There are also other solutions that people have written that might help with updating a full graph.

Finally, if you object graph is not very large, you can get away with getting DbEntityEntry and calling SetValues on each navigational property. But if you do have a large graph and want something automatic I would try something like GraphDiff first.

As a part of my transition from “wantrepreneuer” to entrepreneur, I’ve been indulging in a great amount of business and motivational content. While on my way to work, I was listening to one of my favorite podcasts, The Entrepreneur On Fire. One of the guests recommended a book that he said completely shifted his mindset about business and put all the pieces together. It got me interested, so I picked up a copy from audible.com. This post is dedicated to the review of that audio book, The E-Myth Revisited: Why Most Small Businesses Don’t Work and What to Do About It. The following is a summary of the concepts that I thought were valuable and my reflections on those ideas.

Three Critical Roles

In order to create a business that’s going to stand the test of time and continue growing, you need to have the following three roles: Entrepreneur, Manager, and Technician. All three must be equal in the amount of strength, energy, and time devoted to it. The entrepreneur does the strategic thinking, planning, innovating, and has a vision for the future. The manager makes sure the established process is followed; she makes sure stuff gets done and brings order to the chaos. The technician works on the product itself.

Because software engineers are great at building things, we don’t necessarily notice or pay enough attention to the lack of other equally important roles in our business. We concentrate almost all of our energy on building things, which is only a one third of a successful business.

Work On Your Business Rather Than In It

When you work in your business, you become self-employed. Working on your business means developing it and creating a system so that you can leverage other people’s time and grow your business. The system has to be well-established and easy enough to be followed by your future employees.

This is where I have a lot to learn. While working on the idea, I really need to put together a list of things that can be completed by other people and not try to do everything myself. Even development work can be outsourced. I understand it won’t be as good as something that I would write, but I think it’s up to me to create a system that will have those quality checks built in. As an entrepreneur, there must be other more important tasks like talking to potential customers and figuring out their pain points rather than creating a perfect data access layer.

Divide Roles and Assign Accountability

When starting a new venture, it’s important to write down all the positions that you envision for your business as it matures. For example, you will have a Chief Executive Officer, a Chief Operating Officer, a Vice President of Sales, Vice President of Marketing, Vice President of Operations, and then you will have your managers and other staff. Once you have all those positions written down, you assign people to be responsible for those roles. You might end up with 12 or more roles. If it’s just you and your partner, then each of you will have to assume many roles. The point is to divide the roles and hold everyone accountable. So, if one of your roles is V.P. of Marketing, then it’s your responsibility to bring customers in the door, and you have all the decision-making ability in that domain. It is also important to have a different mindset when performing a particular job; you must make a mental shift and think to yourself that right now I’m performing job x and from that position I’ll be making my decisions and taking action.

When your business starts to grow, you will slowly hire people to handle some of your responsibilities, so you will no longer be responsible for them.

To ensure that I don’t make the same mistake twice, I will work on making sure that roles are clearly divided when I start a new venture. I’ve had many experiences starting with partners and arguing over many different subjects. Now I see that the problem was that we didn’t have clearly established roles and people assigned. If V.P. of Marketing is your role, then it’s your final decision—not the guy who does your development work—on how you want to send out those email campaigns. Finally, if you are not contributing efficiently in your assigned job, you need to be fired or replaced in that role.

Create a System for Average Skills

If your business depends on a person who is a genius, then you really can’t replace that person, and if he or she leaves, you would be out of business. Building a business in a way that enables an average person to perform a job well is very important because now you can hire anyone and your quality won’t suffer. You add safety nets and create checklists to ensure quality is met.

Focus on Building a Business Rather Than Building a Product

Building a system is more important than building a product. A successful business can build many different products and then change them to adapt to the market. If you lock yourself into a specific product, then you are really at a disadvantage because if the market shifts, you will be out of your job.