I am developing a windows app that performs some common TFS tasks using the 2010 Beta 2 API (like creating new team projects, new work items, selective build, etc. ).
In the process of editing existing work items, I should be able to automatically set the 'Reason' field's values according to state change of the WI (mimic-ing Visual Studio). (eg)- When I edit a bug, when state changes from Active to Resolved, the default Reason is 'Fixed' and similarly the default Reason='Deferred' when state goes from Active to Closed. (As defined in the work item type definition xml file. ) This transition is easy to capture and implement inside a simple event handler on the form, since the initial state will be Active when the Bug is edited for the first time.
I want to know how to implement the remaining transitions like Resolved to Closed (Reason=Fixed), Resolved to Active (Reason=Test failed/Not fixed) or Closed to Active (Reason=Reactivated/Regression).
I know there is a method called WorkItem.GetNextState(current_state,action), but this doesn't help as it requires a specific action.
What I have done so far is shown below:
void cmbBugState_SelectedIndexChanged(object sender, EventArgs e)
{
//private enum bugWorkFlows{"Fixed","Deferred","Duplicate","As Designed","Cannot Reproduce","Obsolete","Test Failed","Not Fixed","Reactivated","Regression"}
string[] activeToResolvedReasons = { "Fixed", "Deferred", "Duplicate", "As Designed", "Cannot Reproduce", "Obsolete" };
string[] resolvedToActiveReasons = { "Test Failed", "Not fixed" };
string[] resolvedToClosedReasons = activeToResolvedReasons;
string[] closedToActiveReasons = { "Reactivated", "Regression" };
string[] activeToClosedReasons = activeToResolvedReasons;
cmbBugReason.Items.AddRange(activeToResolvedReasons);
// Set the default reason according to change of state of the work item.
if (cmbBugState.SelectedItem.ToString() == "Resolved")
{
cmbBugReason.Enabled = true;
cmbBugReason.SelectedItem = activeToResolvedReasons[0];
}
if (cmbBugState.SelectedItem.ToString() == "Closed")
{
cmbBugReason.Enabled = true;
cmbBugReason.SelectedItem = activeToResolvedReasons[1];
}
}
Can anyone show how to handle these events on the form?
Thanks,
Tara.
I tried GetNextState. It was never reliable enough for what I needed.
So I "rolled my own" state transition code that has worked very well for me when I am moving from State "A" to State "B". It is a bit long, but it should have what you are looking for in it.
As a side note: Because this does not use the GetNextState method it has to get the next state somehow. The way it does this is by downloading the XML of the work item type in question. It parses that out and uses that to make a Transition list (_allTransistions).
The permissions levels in TFS 2010 needed to do this are: Team Foundation Administrators or Project Administrators. (As a side note, in TFS 2008 and 2005 all valid users could do this.)
The full code that uses this can be found in the WorkItemHelpers.cs file in the TFS Aggregator project on codeplex.
public static void TransitionToState(this WorkItem workItem, string state, string commentPrefix)
{
// Set the sourceWorkItem's state so that it is clear that it has been moved.
string originalState = (string)workItem.Fields["State"].Value;
// Try to set the state of the source work item to the "Deleted/Moved" state (whatever is defined in the file).
// We need an open work item to set the state
workItem.TryOpen();
// See if we can go directly to the planned state.
workItem.Fields["State"].Value = state;
if (workItem.Fields["State"].Status != FieldStatus.Valid)
{
// Revert back to the orginal value and start searching for a way to our "MovedState"
workItem.Fields["State"].Value = workItem.Fields["State"].OriginalValue;
// If we can't then try to go from the current state to another state. Saving each time till we get to where we are going.
foreach (string curState in workItem.Type.FindNextState((string)workItem.Fields["State"].Value, state))
{
string comment;
if (curState == state)
comment = commentPrefix + Environment.NewLine + " State changed to " + state;
else
comment = commentPrefix + Environment.NewLine + " State changed to " + curState + " as part of move toward a state of " + state;
bool success = ChangeWorkItemState(workItem, originalState, curState, comment);
// If we could not do the incremental state change then we are done. We will have to go back to the orginal...
if (!success)
break;
}
}
else
{
// Just save it off if we can.
string comment = commentPrefix + "\n State changed to " + state;
ChangeWorkItemState(workItem, originalState, state, comment);
}
}
private static bool ChangeWorkItemState(this WorkItem workItem, string orginalSourceState, string destState, String comment)
{
// Try to save the new state. If that fails then we also go back to the orginal state.
try
{
workItem.TryOpen();
workItem.Fields["State"].Value = destState;
workItem.History = comment;
workItem.Save();
return true;
}
catch (Exception)
{
// Revert back to the original value.
workItem.Fields["State"].Value = orginalSourceState;
return false;
}
}
/// <summary>
/// Used to find the next state on our way to a destination state.
/// (Meaning if we are going from a "Not-Started" to a "Done" state,
/// we usually have to hit a "in progress" state first.
/// </summary>
/// <param name="wiType"></param>
/// <param name="fromState"></param>
/// <param name="toState"></param>
/// <returns></returns>
public static IEnumerable<string> FindNextState(this WorkItemType wiType, string fromState, string toState)
{
var map = new Dictionary<string, string>();
var edges = wiType.GetTransitions().ToDictionary(i => i.From, i => i.To);
var q = new Queue<string>();
map.Add(fromState, null);
q.Enqueue(fromState);
while (q.Count > 0)
{
var current = q.Dequeue();
foreach (var s in edges[current])
{
if (!map.ContainsKey(s))
{
map.Add(s, current);
if (s == toState)
{
var result = new Stack<string>();
var thisNode = s;
do
{
result.Push(thisNode);
thisNode = map[thisNode];
} while (thisNode != fromState);
while (result.Count > 0)
yield return result.Pop();
yield break;
}
q.Enqueue(s);
}
}
}
// no path exists
}
private static readonly Dictionary<WorkItemType, List<Transition>> _allTransistions = new Dictionary<WorkItemType, List<Transition>>();
/// <summary>
/// Deprecated
/// Get the transitions for this <see cref="WorkItemType"/>
/// </summary>
/// <param name="workItemType"></param>
/// <returns></returns>
public static List<Transition> GetTransitions(this WorkItemType workItemType)
{
List<Transition> currentTransistions;
// See if this WorkItemType has already had it's transistions figured out.
_allTransistions.TryGetValue(workItemType, out currentTransistions);
if (currentTransistions != null)
return currentTransistions;
// Get this worktype type as xml
XmlDocument workItemTypeXml = workItemType.Export(false);
// Create a dictionary to allow us to look up the "to" state using a "from" state.
var newTransistions = new List<Transition>();
// get the transistions node.
XmlNodeList transitionsList = workItemTypeXml.GetElementsByTagName("TRANSITIONS");
// As there is only one transistions item we can just get the first
XmlNode transitions = transitionsList[0];
// Iterate all the transitions
foreach (XmlNode transitionXML in transitions)
{
// See if we have this from state already.
string fromState = transitionXML.Attributes["from"].Value;
Transition transition = newTransistions.Find(trans => trans.From == fromState);
if (transition != null)
{
transition.To.Add(transitionXML.Attributes["to"].Value);
}
// If we could not find this state already then add it.
else
{
// save off the transistion (from first so we can look up state progression.
newTransistions.Add(new Transition
{
From = transitionXML.Attributes["from"].Value,
To = new List<string> { transitionXML.Attributes["to"].Value }
});
}
}
// Save off this transition so we don't do it again if it is needed.
_allTransistions.Add(workItemType, newTransistions);
return newTransistions;
}
Related
I want to remove existing route from RouteCollection and want to add new route with same route name in nopCommerce 4.00 via plugin
Existing route name:
//home page
routeBuilder.MapLocalizedRoute("HomePage", "",
new { controller = "Home", action = "Index" });
I Want to replace it with
routeBuilder.MapLocalizedRoute("HomePage", "",
new { controller = "CustomPage", action = "Homepage" });
I tried several ways but not get any luck.
In my case, I have to replace the robots.txt generation.
I created a new public controller in my plugin, and I copy the original action here:
public class MiscCommonController : BasePublicController
{
#region Fields
private readonly ICommonModelFactory _commonModelFactory;
#endregion Fields
#region Ctor
public MiscCommonController(
ICommonModelFactory commonModelFactory
)
{
this._commonModelFactory = commonModelFactory;
}
#endregion Ctor
#region Methods
//robots.txt file
//available even when a store is closed
[CheckAccessClosedStore(true)]
//available even when navigation is not allowed
[CheckAccessPublicStore(true)]
public virtual IActionResult RobotsTextFile()
{
var robotsFileContent = _commonModelFactory.PrepareRobotsTextFile();
return Content(robotsFileContent, MimeTypes.TextPlain);
}
#endregion Methods
}
After this I create a RouteProvider for my plugin, and I replaced the original route to my own one.
public partial class RouteProvider : IRouteProvider
{
/// <summary>
/// Gets a priority of route provider
/// </summary>
public int Priority => -1;
/// <summary>
/// Register routes
/// </summary>
/// <param name="routeBuilder">Route builder</param>
public void RegisterRoutes(IRouteBuilder routeBuilder)
{
Route route = null;
foreach (Route item in routeBuilder.Routes)
{
if (item.Name == "robots.txt")
{
route = item;
break;
}
}
if (route != null) routeBuilder.Routes.Remove(route);
routeBuilder.MapRoute(
"robots.txt",
"robots.txt",
new { controller = "MiscCommon", action = "RobotsTextFile" }
);
}
}
That's all.
After this implementation, the routing works fine, and the get request landed in my own controller, which is act like the original.
Now, I can replace the generation logic with my own.
I hope it helps.
in the RouteProvider.cs of your plugin write these codes (based on your names):
var lastExistingRoute= routeBuilder.Routes.FirstOrDefault(x => ((Route)x).Name == "HomePage");
routeBuilder.Routes.Remove(lastExistingRoute);
routeBuilder.MapRoute("HomePage", "",
new { controller = "CustomPage", action = "Homepage", });
and the below codes worked for myself version 4.20:
var lastDownloadRoute=routeBuilder.Routes.FirstOrDefault(x => ((Route)x).Name == "GetDownload");
routeBuilder.Routes.Remove(lastDownloadRoute);
routeBuilder.MapRoute("GetDownload", "download/getdownload/{guid}/{agree?}",
new { controller = "AzTechProduct", action = "GetPayed", });
There are two potential ways to deal with this in nopCommerce 4.3 that I see with a quick examination of the code.
First, you could create an IRouteProvider, add your route that has the same signature as the one you wish to 'delete' and make sure the Priority on the provider is greater than 1.
Doing this will basically override the default route built into Nop. This is my preferred method.
public partial class RouteProvider: IRouteProvider
{
public void RegisterRoutes(IEndpointRouteBuilder endpointRouteBuilder)
{
var pattern = string.Empty;
if (DataSettingsManager.DatabaseIsInstalled)
{
var localizationSettings = endpointRouteBuilder.ServiceProvider.GetRequiredService<LocalizationSettings>();
if (localizationSettings.SeoFriendlyUrlsForLanguagesEnabled)
{
var langservice = endpointRouteBuilder.ServiceProvider.GetRequiredService<ILanguageService>();
var languages = langservice.GetAllLanguages().ToList();
pattern = "{language:lang=" + languages.FirstOrDefault().UniqueSeoCode + "}/";
}
}
// Handle the standard request
endpointRouteBuilder.MapControllerRoute("Wishlist", pattern + "wishlist/{customerGuid?}",
new { controller = "MyShoppingCart", action = "Wishlist" });
return;
}
public int Priority => 100;
}
The key to the code above is the Priority value. This route will get added to the list first and will therefore take precedence over the default route. Using this technique eliminates the need to delete the default route.
The second possible method turns out to not work because the endpointRouteBuilder.DataSources[n].Endpoints collection is read only. So, as far as I know, you can't remove mappings from that list after they have been added.
I am working on a multilingual ASP.NET MVC application (MVC4).
I want to make my resource file strings to be editable at runtime without recompiling the application and without app pool recycling And it doesn't look possible with .resx file, so I migrate to store string resources in Database.
I have to Get Each Label/String Resource From Database, so there will be more hits to database for each request. How to fix that?
I have googled around and someone suggests to load the resource in a dictionary and store it as application variable, at login/Sign In page and use that dictionary as resource instead of database hit.
I am confused, what will be effective approach.Can someone guide me in right direction to avoid more database hits?
Any help/suggestions will be highly appreciated.
Thanks
I ran into the same concerns using .resx files for localization. They just did not work well when the persons doing the translation were not programmers. Now, we have a translation page in our admin area. Works great.
One area which we still don't have a good solution for are the data annotations, which still use the .resx files. I have trimmed the source below to remove any references to our actual database structures or tables.
There is a fallback to using the underlying .resx file, if an entry does not exist in the database. If there is not an entry in the .resx file, I split the word whenever a capitol letter is found ( CamelSpace is a string extension method ).
Lastly, depending on your implementation, you may need to remove the context caching, especially if you are caching out of process.
A few examples of usage:
#LanguageDb.Translate("Enter your first name below","FirstNamePrompt")
#LanguageDb.Me.FirstName
#String
.Format(LanguageDb
.Translate(#"You can be insured for
{0} down and {1} payments of {2}"),
Model.Down,Model.NumPayments,
Model.InstallmentAmount)
public class LanguageDb : DynamicObject
{
public static dynamic Me = new LanguageDb();
private LanguageDb() { }
public static string Translate(string englishPhrase, string resourceCode = null)
{
return GetTranslation(englishPhrase, resourceCode) ?? englishPhrase;
}
public override bool TryGetMember(GetMemberBinder binder, out object result)
{
result = GetTranslation(binder.Name);
return true;
}
private static string GetTranslation(string resourceName, string resourceCode = null)
{
resourceCode = resourceCode ?? resourceName;
if (resourceCode.Contains(" ") || resourceCode.Length > 50)
{
resourceCode = resourceName.GetHashCode().ToString(CultureInfo.InvariantCulture);
}
var lang = (string)HttpContext.Current.Request.RequestContext.RouteData.Values["lang"] ?? "en";
// cache entries for an hour
var result = Get(subagent + "_" + lang + "_" + resourceCode, 3600, () =>
{
// cache a datacontext object for 30 seconds.
var context = Get("_context", 30, () => new YourDataContext()) as YourDataContext;
var translation = context.Translations.FirstOrDefault(row => row.lang == lang && row.Code == resourceCode);
if (translation == null)
{
translation = new Lookup {
Code = resourceCode,
lang = lang,
Value = Language.ResourceManager.GetString(resourceName, Language.Culture)
?? resourceName.CamelSpace()
};
context.Translations.Add(translation);
context.SaveChanges();
}
return translation.Value;
});
return result;
}
public override bool TrySetMember(SetMemberBinder binder, object value)
{
// ignore this
return true;
}
public static T Get<T>(string cacheId, int secondsToCache, Func<T> getItemCallback) where T : class
{
T item = HttpRuntime.Cache.Get(cacheId) as T;
if (item == null)
{
item = getItemCallback();
if (secondsToCache > 0)
{
HttpRuntime.Cache.Insert(
cacheId, item, null, Cache.NoAbsoluteExpiration,
new TimeSpan(0, 0, secondsToCache), CacheItemPriority.Normal, null);
}
else
{
HttpRuntime.Cache.Insert(cacheId, item);
}
}
return item;
}
}
I have this code it works well EXCEPT I want to ensure that the expiration bundle is in the database and I dont want to create this database manually. What is the correct way to initialize a database with the expiration bundle enabled?
_documentStore = new DocumentStore()
{
Url = SettingsManager.RavenDbUrl,
DefaultDatabase = SettingsManager.RavenDbDatabaseName
};
_documentStore.Initialize();
Well I couldnt find docs and I couldnt find help so I cobbled this together:
static class RavenDbExtensions
{
/// <summary>
/// Ensure a bundle is activated
/// </summary>
/// <param name="documentStore"></param>
/// <param name="bundleName"></param>
/// <param name="databaseName"></param>
public static void ActivateBundle(this IDocumentStore documentStore, string bundleName, string databaseName)
{
using (var session = documentStore.OpenSession())
{
var databaseDocument = session.Load<DatabaseDocument>("Raven/Databases/" + databaseName);
var settings = databaseDocument.Settings;
var activeBundles = settings.ContainsKey(Constants.ActiveBundles) ? settings[Constants.ActiveBundles] : null;
if (string.IsNullOrEmpty(activeBundles))
settings[Constants.ActiveBundles] = bundleName;
else if (!activeBundles.Split(new char[]{';'}).Contains(bundleName, StringComparer.OrdinalIgnoreCase))
settings[Constants.ActiveBundles] = activeBundles + ";" + bundleName;
session.SaveChanges();
}
}
}
Then I do this little dance when initializing the document store. It seems to work well. It isnt clear whether the bundle is named Expiration or DocumentExpiration so I try both it doesnt crash and it seems to fold in the expiration functionality I need.
_documentStore = new DocumentStore()
{
Url = SettingsManager.RavenDbUrl
};
_documentStore.Initialize();
_documentStore.ActivateBundle("Expiration", Assembly.GetExecutingAssembly().GetName().Name);
_documentStore.ActivateBundle("DocumentExpiration", Assembly.GetExecutingAssembly().GetName().Name);
_documentStore.DefaultDatabase = Assembly.GetExecutingAssembly().GetName().Name;
I have a custom sitecore button which changes the template of the current item, simple enough.
However as part of this I'm trying to also migrate the renderings of the old layout to a new layout if it's of a certain sublayout type by ItemId. However the ItemId that is returned is always null, the only value I get back from the RenderingDefinition is the UniqueId.
What am I doing wrong?
I have used this blog post as a guide.
The Code
public class ConvertToNewTemplateCommand : Command
{
protected void Run(ClientPipelineArgs args)
{
if (!SheerResponse.CheckModified())
return;
Item item = Context.ContentDatabase.Items[args.Parameters["id"]];
if (args.IsPostBack)
{
if (args.Result == "yes")
{
//Get current layout details
var originalLayoutXml = item[FieldIDs.LayoutField];
//Get new template
TemplateItem hubTemplate = Context.ContentDatabase.GetTemplate("some guid...");
//Change template
item.ChangeTemplate(hubTemplate);
//Reset laytout
ResetLayout(item);
//Get reset layout
var newLayoutXml = item[FieldIDs.LayoutField];
//Add all the module containers to the new layout in the central column
MoveModuleContainers(item, originalLayoutXml, newLayoutXml);
}
}
}
private void MoveModuleContainers(Item item, string oldXml, string newXml)
{
var oldLayout = LayoutDefinition.Parse(oldXml);
var newLayout = LayoutDefinition.Parse(newXml);
bool updated = false;
var oldRenderings = (oldLayout.Devices[0] as DeviceDefinition).Renderings;
var newRenderings = (newLayout.Devices[0] as DeviceDefinition).Renderings;
foreach (RenderingDefinition rendering in oldRenderings)
{
// Here is where the rendering.ItemID is always null
if (rendering != null && !String.IsNullOrEmpty(rendering.ItemID) && new Guid(rendering.ItemID) == new Guid("matching guid..."))
{
rendering.Placeholder = "middlecolumn";
newRenderings.Add(rendering);
updated = true;
}
}
if (updated)
{
// Save item...
}
}
}
I got onto Sitecore support in the end which informed me that I should use:
Sitecore.Data.Fields.LayoutField.GetFieldValue(item.Fields[Sitecore.FieldIDs.LayoutField])
instead of:
item[FieldIDs.LayoutField]
to get the items layoutField correctly. This results in the rendering values being parsed correctly and as they say the rest is history.
This is a c#/asp.net project. The full error message I get is:Error 0194: All artifacts loaded into the item collection must have the same version. Multiple versions were encountered.
This project was started as a 3.5 and upgraded to 4.0. When I try to test any of the methods I get the error that I posted in the subject line. I am going to include the actual lines that it throws the exception on. If there is anything in people need to see to try to help let me know and I post it as well. Any help will be appreciated, I am having no luck with this.
/// <summary>
/// Initializes a new SFBExternalPaymentsEntities object using the connection string found in the 'SFBExternalPaymentsEntities' section of the application configuration file.
/// </summary>
public SFBExternalPaymentsEntities() : base("name=SFBExternalPaymentsEntities", "SFBExternalPaymentsEntities")
{
this.ContextOptions.LazyLoadingEnabled = false;
OnContextCreated();
}
/// <summary>
/// Initialize a new SFBExternalPaymentsEntities object.
/// </summary>
public SFBExternalPaymentsEntities(string connectionString) : base(connectionString, "SFBExternalPaymentsEntities")
{
this.ContextOptions.LazyLoadingEnabled = false;
OnContextCreated();
}
/// <summary>
/// Initialize a new SFBExternalPaymentsEntities object.
/// </summary>
public SFBExternalPaymentsEntities(EntityConnection connection) : base(connection, "SFBExternalPaymentsEntities")
{
this.ContextOptions.LazyLoadingEnabled = false;
OnContextCreated();
}
#endregion
Added a method calling the constructor.
public static CreditCardResponse AuthCapture(CreditCard newCC)
{
ACHResponse validateResponse = CreditCard.Validate(newCC);
if (validateResponse.Status == "Accepted")
{
Profile currentProfile = new Profile();
currentProfile = ProfilesGateWay.GetByID(newCC.ProfileID);
CreditCardTransaction newCCTransaction = CreateCreditCardTransaction(newCC, currentProfile);
ServiceClient client = new ServiceClient();
CreditCardTransactionResponse cctResponse = client.CreditCardAuthorizeAndCapture(newCCTransaction);
client.Close();
CreditCardResponse ccResponse = CreateCCResponse(cctResponse);
if (ccResponse.ResponseCode == 1)
{
int authAVS = ConvertAVStoInt(ccResponse.AVSResponse);
int appAVS = ConvertAVStoInt(newCC.AVLevel);
bool isAVSPass = CompareAVS(authAVS, appAVS);
if (isAVSPass == false)
{
ccResponse.ResponseCode = 0;
ccResponse.ResponseReasonCode = 99;
ccResponse.ResponseText = "Did not meet your AVS requirements";
return ccResponse;
}
else
{
int newCCID = CreateCreditCardRecord(newCC, currentProfile, cctResponse, "Captured", "Auth_Capture");
CreditCardRecord updateCC = CreditCardRecordsGateWay.GetByID(newCCID);
updateCC.CaptureOn = DateTime.Now;
CreditCardRecordsGateWay.Update(updateCC);
return ccResponse;
}
}
else
{
return ccResponse;
}
}
CreditCardResponse newCCResponse = new CreditCardResponse();
newCCResponse.ResponseCode = 0;
newCCResponse.AchResponse = validateResponse;
return newCCResponse;
}
public static CreditCardResponse PriorAuthCapture(CreditCard newCC)
{
CreditCardRecord ccRecord = CreditCardRecordsGateWay.GetByCCGateWayID(newCC.CreditCardTransactionID);
ServiceClient client = new ServiceClient();
CreditCardTransaction ccTransaction = client.CreditCardGetTransactionById(ccRecord.CCGatewayID);
CreditCardTransactionResponse cctResponse = client.CreditCardPriorAuthorizationCapture(ccTransaction);
if (cctResponse.ResponseCode == 1)
{
ccRecord.Status = "Captured";
ccRecord.CaptureOn = DateTime.Now;
}
CreditCardResponse ccResponse = CreateCCResponse(cctResponse);
return ccResponse;
}
protected static int CreateCreditCardRecord(CreditCard newCC, Profile currentProfile, CreditCardTransactionResponse cctResponse, string status, string transactionType)
{
CreditCardRecord newCCRecord = new CreditCardRecord();
newCCRecord.Address = newCC.Address;
newCCRecord.AddressVerificationLevel = newCC.AVLevel;
newCCRecord.Amount = newCC.Amount;
newCCRecord.CardCode = newCC.CardCode;
newCCRecord.CardNumber = newCC.CardNumber;
newCCRecord.CCGatewayID = cctResponse.CreditCardTransactionID;
newCCRecord.City = newCC.City;
newCCRecord.CompanyName = newCC.CompanyName;
newCCRecord.CreateBy = currentProfile.ACHCompanyName;
newCCRecord.CreateOn = DateTime.Now;
newCCRecord.Description = newCC.Description;
newCCRecord.Expiration = newCC.Expiration;
newCCRecord.FirstName = newCC.FirstName;
newCCRecord.LastName = newCC.LastName;
newCCRecord.Profile.ProfileID = currentProfile.ProfileID;
newCCRecord.State = newCC.State;
newCCRecord.Status = status;
newCCRecord.TransactionType = transactionType;
newCCRecord.Zip = newCC.Zip;
return CreditCardRecordsGateWay.Insert(newCCRecord);
}
You have just posted the constructors to your SFBExternalPaymentsEntities class, but you seem to say that you get an exception when you call a method that returns a collection of entities, which makes send with the exception message you are getting. The chances are the problem lies within the method you are calling, or in the code calling it rather than in the constructor code you have posted. Can you post some more relevent code or explain how the code you have posted relates to the exception.
I encountered the same problem when i updated one of my projects from .net 4.0 to 4.5, the reason probably was because there was another .edmx file in an other project that was referenced in the target project.
Solution to issue : Updated the other project that was referenced and contained .edmx file to .net 4.5 and then, Right-Clicked on every .edmx files in these 2 projects and then selected 'Run Custom Tool'
It worked for me, hope that it works for everyone reading this article