Introspecting maximum column length using IronPython and EDM - entity-framework

I am engaged in an ETL project using IronPython and loading into a SQL Server database represented by an EDM 4.1 model provided to me. While I can generally load and save the data without trouble, I'm plagued by string length overruns in the incoming data. This throws an exception in the final .SaveChanges() call to the EDM. I receive no information in the exception about what entity, entity class, or property threw the error.
I would like to modify my code so that it checks the max length of the column for the database's metadata at the time of assignment. It appears that this metadata is not available through the entity class but rather using the MetadataWorkspace of the EDM context object.
In order to call .GetItems() on the MetadataWorkspace, I need to provide an enumeration value from System.Data.Metadata.Edm.Dataspace:
.GetItems(System.Data.Metadata.Edm.Dataspace.CSpace)
Unfortunately, I don't seem to be able to reference System.Data.Metadata in any way. I cannot get beyond System.Data:
>>> import clr
>>> clr.AddReference("System.Data")
>>> import System.Data
>>> clr.AddReference("System.Data.Metadata")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
IOError: System.IO.IOException: Could not add reference to assembly System.Data.Metadata
at IronPython.Runtime.ClrModule.AddReference(CodeContext context, String name)
Does anyone have experience in introspecting EDM metadata from IronPython?

To be able to access MetadataWorkspace you need to add reference to System.Data.Entity.dll (if you don't have one) and then drop down to ObjectContext like this:
((IObjectContextAdapter)ctx).ObjectContext.MetadataWorkspace
where ctx is your DbContext derived class.
Also in EF 4.1 there is a Validation feature implemented. I am not sure if this what throws the exception because it should give you all the details - including property name and a reference to the entity where the validation error occured. If the exception is thrown by the database it would mean that Validation is turned off. If you turned it on it would check facets and throw an execption if they are validated. Here are the links to blog posts on Validation:
http://blogs.msdn.com/b/adonet/archive/2011/05/27/ef-4-1-validation.aspx
http://blogs.msdn.com/b/adonet/archive/2010/12/15/ef-feature-ctp5-validation.aspx

Related

Entity Framework Core: SaveChanges() NON-async throws "A second operation was started on this context before a previous operation completed."

I am fairly new to Entity Framework and everything has been moving smoothly, until I encountered this error. My code is attempting to save children of a parent table using SaveChanges() but I get this error:
A second operation was started on this context before a previous operation completed. This is usually caused by different threads concurrently using the same instance of DbContext.
This message seems tied to async calls and having to use await - SaveChangesAsync(). However I am NOT calling the async version of the SaveChanges() method but still get a thread error message.
My code is fairly simple:
public void CreateRange(IList<Section> sections)
{
// Add new sections and save context.
_SqlRunnerContext.sectionsDbSet.AddRange(sections);
_SqlRunnerContext.SaveChanges(); // This line throws the error.
}
The error seems to occur when there are at least two entries in the list. Which makes me think it's the way that Entity Framework is handling the save internally.
The code that calls this method creates a new repository which in turn creates a new dao and SqlContext. Given this I wouldn't think it would be something outside of this code causing the issue. I have also tried a foreach loop and save each item individually with the same error.
If anyone could give me a suggestion or idea what to try, it would be much appreciated.
Thanks again,
Adam
Instead of deleting all records then re-inserting. I change the code to simply update if it exists and add if new. This has resolved the issue.

EclipseLink-Moxy Unable to load custom DomHandler class while instantiating JAXB context

I am using Eclipselink Moxy Implementation of JAXB in my project to map complex XML to String Object using XmlAnyElement.
For this I have implemented DomHandler named as LayoutHandler.
I am using JAXB for resteasy web services deployed in JBoss 6.
I am facing Below issue intermittently -
Exception [EclipseLink-50033] (Eclipse Persistence Services - 2.5.0.v20130507-3faac2b):
org.eclipse.persistence.exceptions.JAXBException
Exception Description: The DomHandlerConverter for DomHandler
[com.**.LayoutHandler] set on property [layoutXml] could not be
initialized.
Internal Exception: java.lang.ClassNotFoundException:
com.**.LayoutHandler from
BaseClassLoader#5c0b3ad0{vfs:///*/*/jboss-server/server/all/deployers/resteasy.deployer}
While EclipseLink Moxy is instantiating JAXBContext using JAXBContext.newInstance(classes, properties)
After spending some time in debugging and analyzing the issue I could figure out that ClassLoader of resteasy is getting used to load LayoutHandler class instead of my application class loader(vfs://///jboss-server/server/all/deploy/app_name.ear/app_name.war/) which is causing the issue as its unable to find the LayoutHandler class.
When I bounce the server, issue is getting resolved so I am unable to find out the exact root cause. Any help will be appreciated.
Further debugging into org.eclipse.persistence.jaxb.JAXBContextFactory revealed that below two classes are getting passed to createContext() method of JAXBContextFactory -
org.jboss.resteasy.plugins.providers.jaxb.JaxbCollection
com.**.Model_class
public static javax.xml.bind.JAXBContext createContext(Class[] classesToBeBound, Map properties) throws JAXBException {
ClassLoader loader = null;
if (classesToBeBound.length > 0) {
loader = classesToBeBound[0].getClassLoader();
}
return createContext(classesToBeBound, properties, loader);
}
In above method classloader of first class is getting used to load the custom DomHandler later on.
When first element in array is model class at that time code is working fine as application context class loader is getting used but when the first element in array is JaxbCollection rest easy context class loader is getting used and its throwing mentioned exception.
This issue is occurring intermittently as order of elements in array is varying which might be due to the use of HashSet to hold the elements of type Class by caller of this method which is passing the classesToBeBound array
Note: I have replaced actual package names with *.
I'm surprised it works on a bounce... all of your JAXB bits need to line up, you should be using the moxy jaxb provider at all times. If it's failing after initial deploy, then working after a bounce, I suspect that you want to specify the moxy jaxb provider in your system properties ( -Djavax.xml.bind.context.factory=org.eclipse.persistence.jaxb.JAXBContextFactory ) and ensure that they're available to jboss when your app is not deployed.

Where does Entity Framework code-first migration deploy database

I have a library for the data access layer where it uses Entity Framework, in the DbContext class I pass the connection string name DefaultConnection through the constructor, then I add this connection string to the app.config file for this library.
But when I update to the database I find the database is not created into this connection string server and catalogue?
Anybody please explain how migration and update database handle connection strings?
Your library can't access the app.config file in run time. Only executable components can (a web api, a console application, etc.). You have to define the connectionString value in the config file of the executable component that uses your library, not in the library's app.config file. The only scenario when the library's app.config file connection string can be used is when running Entity Framework commands in the Package Manager console (like add-migration and similar ones).
The recommended way to deal with connection strings is that the data layer library doesn't care at all about the responsibility of obtaining the connection string value. Instead, the client that uses the library should provide the connection string when instantiating the data layer classes. The responsibility of getting the value should be in that client component, using code like this to get the value to be passed to the data layer:
var connectionString = Configuration.GetConnectionString("MyConnectionString");
A common practice is to use a dependency injection component (like Autofac) so that the client injects the connection string as a parameter in the DbContext constructor, or in a property, after getting it from the configuration file (or possibly from other place).
There are also several approaches about what parts of your data layer you expose to the client components that use it: you can directly create instances of the DbContext, or use the Repository pattern, or the UnitOfWork pattern. The important concept here is that whenever your client component creates an instance of one of your data layer classes, it has to get the connection string value from wherever it is and pass it to the data layer component (via directly invoking the constructor and passing the connection string value as a parameter, or setting a property, or via your dependency injection component).
More info here and here.
Update: added some info about execution from Package Manager console:
To pass the connection string tothe Package Manager console you can do several things:
Add an explicit parameter ConnectionString to your console commands (the complete connection string, not only the name in the config file). This avoids the need to add the connection string to your library's config file.
Add an explicit parameter ConnectionStringName to your console commands. Define that connection string in the library app.config (but be careful and don't forget that it will only be used from the console, and that the one used in run time is the one in the executable component config file. This approach may lead to some mistakes).
Add a parameterless constructor to your DbContext with the connection string name hard-coded in the base constructor call, like this:
public MyDbContext() : base("DefaultConnection") { ... }
This will be the one that console manager will use. For real code execution use the other constructor with the parameter. Again, the connection string must be defined in the library's app.config file and this may lead to mistakes.
Also, console manager uses by default the configuration from the project selected as start project in your solution. If this project is not the database library it will not work like you want. To fix this you should set your solution as "Multiple start up projects", and select the database layer project in the console manager "Default project" drop down list (or pass a DefaultProject parameter with the data layer project name to your console commands).

Nested Transactions In EF6

I have a method where the DBContext is pass in (this is only POC code).
I then try to open another nested transaction, With this code
using (var cxt = new TestEntities(context.Database.Connection, false))
{
using (DbContextTransaction dbContextTransaction = cxt.Database.BeginTransaction())
{
The call to "BeginTransaction" gives this error:
An exception of type 'System.Data.Entity.Infrastructure.UnintentionalCodeFirstException' occurred in TestEF6.exe but was not handled in user code
Additional information: The context is being used in Code First mode with code that was generated from an EDMX file for either Database First or Model First development. This will not work correctly. To fix this problem do not remove the line of code that throws this exception. If you wish to use Database First or Model First, then make sure that the Entity Framework connection string is included in the app.config or web.config of the start-up project. If you are creating your own DbConnection, then make sure that it is an EntityConnection and not some other type of DbConnection, and that you pass it to one of the base DbContext constructors that take a DbConnection. To learn more about Code First, Database First, and Model First see the Entity Framework documentation here: http://go.microsoft.com/fwlink/?LinkId=394715
I have a Database First Model
Any clues?
Regards
GregJF

ArgumentException when creating instance of object that inherits from ObjectContext

I'm loosely following an excellent series of blog posts by Kazi Manzur Rashid as a learning exercise for learning how to implement some new (for me at least) design patterns, but I'm getting trouble from the start.
I've basically copied his code for the Database, RepositoryBase and RepositoryBaseTests classes, but when I try to run the tests, I get an error message saying
Unable to create instance of class Booking.Infrastructure.EntityFramework.Repositories.Tests.RepositoryBaseTests. Error: System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.ArgumentException: Format of the initialization string does not conform to specification starting at index 0..
Through the debugger I have verified that the exception is thrown on the constructor for the Database class, which looks like this:
public Database(
IConfigurationManager configurationManager,
string connectionstringName)
: base(
GetConnectionString(configurationManager, connectionstringName),
"BookingEntities")
{ // Nothing happens here }
The error is thrown when calling the base constructor, and if I'd hard-code the values that I'm currently sending in, it would look like this:
: base("Dummy connStr", "BookingEntities")
Why doesn't this work?
"Dummy connStr" is not a valid EF connection string.
A valid EF connection string looks like:
connectionString="metadata=res://*/Data.Model.csdl|res://*/Data.Model.ssdl|res://*/Data.Model.msl;provider=System.Data.SqlClient;provider connection string="Data Source=SERVERNAME\SQLDEV2008;Initial Catalog=DBName;Integrated Security=True;MultipleActiveResultSets=True""