entity Framework 5 changing providers at runtime - entity-framework-5

I have an application that runs at several client sites. I have to support different DBMS at the locations (SQL Server, DB2, Oracle). I am converting the application from VC++ 6.0 with an ODBC based data layer to Visual Studio 2012 and would like to use Entity Framework (database first). I am having troubles changing the database provider at runtime in my sample application. I changed the connect string in the app.config from a SQL Server to DB2 connect string and changed the default connection factory. Now when I run the program I can connect to the database (at least there is no error) but when I iterate over the linq results I get the exception:
Unable to cast object of type 'IBM.Data.DB2.DB2Connection' to type 'System.Data.SqlClient.SqlConnection'
Here is the program code:
private void btnList_Click(object sender, EventArgs e)
{
using (var ListBill = new LB402_TestEntities())
{
var queryGroups = from Groups in ListBill.LB_Group
select Groups.GroupName;
foreach (string name in queryGroups)
{
lbGroups.Items.Add(name);
}
}
}
The modifed portions of the app.config are:
<defaultConnectionFactory type="IBM.Data.DB2.Entity.DB2ConnectionFactory, EntityFramework" />
<add name="LB402_TestEntities" connectionString="metadata=res://*/LB402.csdl|res://*/LB402.ssdl|res://*/LB402.msl;provider=IBM.Data.DB2;provider connection string="Server=db210:50000;Database=LISTBILL;uid=uuuuu;pwd=ppppp;"" providerName="System.Data.EntityClient" />
From my searching and reading it seems like I should be able to do this, but I am obviously missing something.

Changing connection string is not enough. EDMX file consist of three part and one is provider specific (that is the .ssdl reference from connection string). You need to have this part for every database you need to support and you need to have EF provider for every such database. The problem is that EDMX designer does not support modelling for multiple providers. So you must either have separate EDMX for every database = huge duplicity or you must start maintaining SSDL files for other databases manually (it is XML).
You should make some small Proof-of-concept with code first mapping and DbContext API because it doesn't have these obstacles - SSDL is generated at runtime from code mapping and provider specified in connection string.

Related

Why doesn't Azure load properly the Interop?

I have a WebApp on Azure that uses a dll. This library needs Interop libraries x86 and x64.
Sometimes, at the restart of the App (I suppose), the App fails due to an exception:
System.EntryPointNotFoundException: Unable to find an entry point named 'sqlite3_config' in DLL 'SQLite.Interop.dll'. at System.Data.SQLite.UnsafeNativeMethods.sqlite3_config_none(SQLiteConfigOpsEnum op) at System.Data.SQLite.SQLite3.StaticIsInitialized() at System.Data.SQLite.SQLiteLog.Initialize() at System.Data.SQLite.SQLiteConnection..ctor(String connectionString, Boolean parseViaFramework) at T_Dox.WebService.SQLiteDb.CreateConnection() at WebService.CeDb.Connect()
The SQLite used is the SQLCipher's one.
What am I missing here? I don't understand why the app stops working suddenly even if I don't make any changes.
The App is a Web Service (.asmx file) that uses a data access layer to perform some business logic.
It was under a web site project, then we moved it into another project, a webapi\mvc project.
The routing bypasses this extension, so it works as before, a simple web service call.
The called web method initializes a business class loaded from another .net library (a VB.Net library).
Inside, this class uses a wrapper to a sqlConnection, in this case the SQLiteConnection.
In its constructor it starts an SQLiteConnection, and normally it works.
Then it performs some CRUD operations ...
So I can represent the operation this way:
[WebService(Namespace = "...")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
public class SampleService : System.Web.Services.WebService
{
[WebMethod]
public ServerInfo Test()
{
var sampleBusinessClass = new SampleBusinessCLass();
sampleBusinessClass.DoSomething();
using(var connection = new SQLiteConnection()) //the constructor is the parameterless one
{
//...
}
}
}
And the stack will be this (this is not the real one):
System.EntryPointNotFoundException: Unable to find an entry point named 'sqlite3_config' in DLL 'SQLite.Interop.dll'.
at System.Data.SQLite.UnsafeNativeMethods.sqlite3_config_none(SQLiteConfigOpsEnum op)
at System.Data.SQLite.SQLite3.StaticIsInitialized()
at System.Data.SQLite.SQLiteLog.Initialize()
at System.Data.SQLite.SQLiteConnection..ctor(String connectionString, Boolean parseViaFramework)
at xxx.WebService.SampleService.Test()
It always works, but sometimes it starts to launch this error until the stop and start of the web application on iss (in our case: Azure).
Inspecting the System.Data.SQlite.dll I can clearly see the entry point and actually it always passes this internal code (no conditions that can bypass this part) and it generally works.
The System.Data.SQlite.dll (1.0.96.0 version) is provided by SqlCypher product. I think it is the original System.Data.SQLite one because at first sight I can see the same assembly manifest and content.
The interop System.Data.SQLite uses is probably modified by SqlCypher team to give their features.
To avoid possible issues we put the interop in the path /bin/x64, then we compile our web app ONLY in x64 and it runs on a x64 environment.

How to configure entity framwork (Model First ) on microsoft azure?

I was using EntityFramwok (code First) in my application, but for some cause i have to change entityframwork approch to Database First. i have configured the project on local successfully, when published the code to microsoft azure server and tried to login in my application it throws an exception: " 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 searched about it on google but can't found any clue, seems i am the only person who got this exception :( does anybody knows about this. I am new to azure so don't know how to change the entityframwork approach there. any help or suggestions will be appreciated :)
I just deployed a database first project to Azure and ran into the identical error. Seems like there is a lot more information when googling now than there was when you asked this question. Regardless, none of it was entirely on point for me though and I had to experiment to come up with the solution.
Here's my scenario:
My database first DB is hosted on Azure as well and the connection string that Azure recommends for ADO.NET is what I put in my Web.Release.config transformation entries. I have two connection strings, one is the default connection and the other is the one that is used for the db first project. The solution was to use the same (functioning) content from the Web.config connection string and only replace the inner portion with Azure db connection string. I was cut & past happy at first and just wiped out the full content of the connection string leading to the error.
Lot's of the info within the connection string is particular to your project and the db first entities you have created in the project. Here are a couple examples from what I have:
You're Web.config should have connection strings for you local dev environment (chances are these were created for you by the DB first wizard):
<configuration>
...
<connectionStrings>
<add name="DefaultConnection" connectionString="Data Source=(LocalDb)\v11.0;AttachDbFilename=|DataDirectory|\aspnet-WebRole1-20150218073037.mdf;Initial Catalog=aspnet-WebRole1-20150218073037;Integrated Security=True" providerName="System.Data.SqlClient" />
<add name="DbFirstModelEntities" connectionString="metadata=res://*/Models.DbFirstModel.csdl|res://*/Models.DbFirstModel.ssdl|res://*/Models.DbFirstModel.msl;provider=System.Data.SqlClient;provider connection string="data source=(localdb)\ProjectsV12;initial catalog=DbFirstData;integrated security=True;MultipleActiveResultSets=True;App=EntityFramework"" providerName="System.Data.EntityClient" />
</connectionStrings>
...
</configuration>
Notice how the dbfirst connection string starts out with a bunch of meta data about the db models. This stuff is important!!
Next comes the correct Web.Release.config connection string transformation (just posting the DB first one, but you'd need to do something similar for any others that you have):
<connectionStrings>
<add name="DbFirstModelEntities"
connectionString="metadata=res://*/Models.DbFirstModel.csdl|res://*/Models.DbFirstModel.ssdl|res://*/Models.DbFirstModel.msl;provider=System.Data.SqlClient;provider connection string="Server=tcp:<yourdatabesserver>.database.windows.net,1433;Database=DbFirstData;User ID=<user>;Password=<password>;Trusted_Connection=False;Encrypt=True;Connection Timeout=30;MultipleActiveResultSets=True;App=EntityFramework""
providerName="System.Data.EntityClient"
xdt:Transform="SetAttributes" xdt:Locator="Match(name)"/>
</connectionStrings>
So long story, if you're encountering this error after publishing to azure: go check your transformations and make sure you're not removing all that important meta data!
While configuring your website and database on the azure server you have to define a connection string and the name of the connection string should not be the same as connection string name in your web.config file. I just did rename the connection string name in my web.config and problem solved. :)

The model backing my context has changed

I have a class library project where my POCO classes live along with a Dbcontext. I am using Code First with data migrations and everything has gone great up to this point. I use the class library in a console application test project and it still works fine there, but I am also trying to use the same exact class library in an MVC project and I get a "The model backing the context has changed since the database was created". Whenever I make a change to the model, I do the database migration update and everything goes well. The model has not still works in the console application just fine.
I have this method in a controller where I am trying to access the context:
public MultiSelectList GetListOfPossibleDispositions()
{
List<DALDevices3.Dispositions> dispositions = new List<Dispositions>();
dispositions = context.Dispositions.GroupBy(d=>d.Description).Select(grp=>grp.First()).ToList();
dispositions.OrderBy(d=>d.Description);
selectListDispositions = new MultiSelectList(dispositions, "id", "Description");
context.Dispose();
return selectListDispositions;
}
Any thought on what might be causing this issue or a possible work around ?
Thanks
In my MVC application I had a connection string name like this:
<add name="DALDevices3.DeviceContextConnectionString" connectionString="Data Source=....
so I removed the connection string since it is code first and still received the same error. I put the connection string back like this:
<add name="DALDevices3.DeviceContext" connectionString="Data Source=....
and the application works. So a connection string is not required in the DAL application, but is needed in the consuming application.

Call to DBContext throws exception (code first, create DB)

I wanted to try EF5 as described here: http://msdn.microsoft.com/en-us/data/jj193542
But as soon as
using (var db = new BloggingContext())
is reached an System.InvalidOperationException is thrown with additional details saying that "The type 'ConsoleApplication1.Program+Blog' was not mapped. Check that the type has not been explicitly excluded by using the Ignore method or NotMappedAttribute data annotation. Verify that the type was defined as a class, is not primitive, nested or generic, and does not inherit from EntityObject."
No database is created. I'm using VS 2012 Express for Windows Desktop and SQL Server 2012. The database explorer can connect to the local SQLExpress instance without problems.
Any ideas?
Cheers, mttmjapj
Okay, found the culprit. I unconsciously put the source for Blog and Post into the program class. Which obviously is nested and therefore can't work.

Separate Read/Write Connection for SubSonic

The security policy at our client's production environment requires that we use separate connection to execute writes and read to and from database. We have decided to use SubSonic to generate our DAL. So I am interested in knowing if it is possible and if yes how?
You can specify the provider SubSonic is using at runtime. So you would specify the read provider (using your read connectionstring) when loading from the database and then specify the write provider (using your write connectionstring) when you want to save to it.
The following isn't tested but I think it should give you the general idea:
SqlQuery query = new Select()
.From<Contact>();
query.ProviderName = Databases.ReadProvider;
ContactCollection contacts = query.ExecuteAsCollection<ContactCollection>();
contacts[0].FirstName = "John";
contacts.ProviderName = Databases.WriteProvider;
contacts.SaveAll();

Resources