Does EF fully support ANY cross-platform database? - mysql

For past few hours, I tried to "port" my current project from Sql Server to MySQL, I ended up with errors like:
The underlying provider does not support the type varchar(max) (or
uniqueidentifier, or something else)
I use POCO, and Code First - I thought, that one of the purposes of EF was to provide easy repository "switching", but it would seam that even basic types are not mapped correctly :/
I also tried SQlite but it is even in worst shape, and as far as I know, Postrage SQL support is also lacking.
So... question is - is there any cross-platform (preferably free) database out there that has real (SQL Server like) support in EF?
Thanks in advance.
Best regards.
Edit:
To by more specific about my approach:
I use POCO, and Code First, I want to automatically create the database if it doesn't exists, I don't use anything special inside my POCO classes, just standard .NET types. Example POCO looks like this:
[Key]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
public int ID { get; set; }
[Required]
[StringLength(128)]
public string Name { get; set; }
[Required]
public int AgencyID { get; set; }
[Required]
public bool IsEnabled { get; set; }
#region NavigationProperties
[NavigationProperty]
public virtual Agency Agency { get; set; }
#endregion
Edit2:
My app.config looks like this:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
<!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 -->
<section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
</configSections>
<entityFramework>
<!--<defaultConnectionFactory type="System.Data.Entity.Infrastructure.SqlConnectionFactory, EntityFramework" />
<providers>
<provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
</providers>-->
<defaultConnectionFactory type="MySql.Data.MySqlClient.MySqlClientFactory, MySql.Data" />
</entityFramework>
</configuration>

You seem to have SqlServer set as your defaultConnectionFactory in the app/wbeb.config file which results in EF using SqlServer types. You need to set the defaultConnectionFactory to a MySQL connection factory.

I struggled with this same error all night. The fix was counter-intuitive but so far so good... It does seem that the issue had to do with old migrations that were set up with LocalDB (SQL Server) yet even deleting the old migrations had no effect. I also spent lots of unnecessary time fiddling with my Web.config, Database Context, etc... I suggest trying the following before banging your head on the wall...
Delete the migrations folder
Try enabling migrations and adding your initial migration (in the PM type "enable-migrations" and then "add-migration init")
If you get the above error in the PM, delete the migrations folder again, then open up MySQL Workbench
Within MySQL Workbench, locate the Schema with the name you gave in your connectionString (will look like database=whateverYouCalledIt)
In that schema, open the tables and find "__migrationhistory"
Right click that table, click select rows, and delete any existing migration entries, then repeat step 2
For some reason this did the trick for me when deleting migrations in the solution explorer had no effect. Apparently, that didn't delete the migration history in the database...
And for the record to the OP, this worked just fine with ASP.net Identity and the MVC Auth system... I think SimpleMembership is now antiquated but then I'm not developing desktop apps...

Related

Login failed for user 'IIS APPPOOL\myApp' when using Entity Framework with MySQL

I'm an Entity Framework newbie who is trying to develop some simple add-on to Sitefinity CMS on top of MySql database.
The database is working perfectly with Sitefinity itself; however, when my own EF code trying to connect with it, I always got the error:
Cannot open database "MyDatabase" requested by the login. The login failed. Login failed for user 'IIS APPPOOL\myApp'.
The connection string I'm using is:
<add connectionString="Server=localhost;Uid=MyUserId;Pwd=MyPassword;Database=dev_MyDatabase;CharacterSet=utf8" providerName="System.Data.SqlClient" dbType="MySQL" name="MyDatabase" />
The user (id and password) is created in MySQL, thus, when trying putting it in IIS (Application Pools > Advanced Settings...), it says "The specified user name does not exist".
Any idea what I'm missing here?
Thanks,
Harry
I see that you are using Entity Framework.
What does your Context look like? If you have a constructor that inherits the base constructor of DbContext, you need to make sure that you pass along the correct name in the parameter. In your case, it should look like this:
public class MyContext : DbContext
{
public MyContext():
base("MyDatabase")
{
}
}

Windsor installer configuration

I have an application built with Windsor, this application has features and al the components are manually registered inside xml which also contains their configuration. This is an example:
<component type="type">
<parameters>
[...]
</parameters>
</component>
I decided to refactor my components and separate them into windsor installers, one installer for each feature. My problem now is to decide where to put the configuration of the components registered inside each installer.
Before this decision, the user could find the appropriate configuration of the components mostly inside the parameters element of xml, and I did not have to write wire logic for that to work.
Now I'm a bit confused because it seems like I don't have anymore such automatism. Since I decided to declare the installers of my application by xml, I think it could be perfect if I could put this configuration inside the installr element like this:
<installers>
<install assembly="myassembly">
<parameters>
[...]
<parameters>
</install>
</installers>
I don't know if Windsor supports this syntax. If it does, then I wonder how I could access it from inside the installer and how to wire it up to my components and services.
Another accettable alternative could be to create and register on xml a component containing all the configuration of my feature:
<components>
<component type="featureConfiguration">
<parameters>
</parameters>
</component>
</components>
In this case I guess that I have to refactor my components to let them receive such type as argument in their constructor whereas before I had direct properties, in other words before I could tell exactly what were the dependencies of my components by looking at the code, with this new form I pass to them the whole configuration but I don't know anymore what specific properties of the configuration are used in this or that component.
To use this second solution and to avoid this confusion I should avoid to pass the whole configuration to my subcomponents, and let that single properties do the work, but I have to find a glue between the properties of this configuration component and the properties of the components and services of the installer.
I think that rather than a component I could also put all my configuration inside the properties element of xml:
<properties>
<featureConfiguration>
[property list]
</featureConfiguration>
</properties>
but again, I have to find the glue between each single property in the list and the properties of my components.
Any help is appreciated.
Thank you.
Maybe you will find this mixed solution helpful, depending on the level of the parameterization of your components that you need. Namely, you could perform the component registration in your installers and set the parameters of the components in a windsor config file. This is useful when you have parameterization needs on few of your components while letting Windsor handle all other dependencies.
Example:
Let's say that you have the following components.
public class MyComponent
{
public MyComponent(MyDependency dependency, string stringParameter, DateTime dateParameter)
{
this.Dependency = dependency;
this.StringParameter = stringParameter;
this.DateParameter = dateParameter;
}
public DateTime DateParameter { get; set; }
public string StringParameter { get; set; }
public MyDependency Dependency { get; set; }
}
public class MyDependency
{
}
Then you could use the following installer to register them.
public class MyInstaller : IWindsorInstaller
{
public void Install(IWindsorContainer container, IConfigurationStore store)
{
container.Register(Component.For<MyComponent>().Named("MyComponent"));
container.Register(Component.For<MyDependency>());
}
}
Note, that we have been explicit about the unique name of the component, set to MyComponent. But you can use also the default full name.
The windsor config file could look like this:
<configuration>
<components>
<component id="MyComponent">
<parameters>
<stringParameter>Some string</stringParameter>
<dateParameter>2013/09/25</dateParameter>
</parameters>
</component>
</components>
</configuration>
And now you can wrap it all together:
WindsorContainer container = new WindsorContainer();
container.Install(Configuration.FromXmlFile("windsor.config"));
container.Install(FromAssembly.This());
Note that the order of invoking the Install method is important; you must first install the config file settings.

Entity Framework Code First Permission/DB Creation Issues

I am attempting to create a db using EF 5 Code First on SQL Server 2008. I can create the db using Integrated Security, but I cannot create the db using a custom user. The code runs the initializer on my home machine for both integrated security and custom user.
The difference in the connection strings is as follows. In addition to these I changed Data Source to Server and Initial Catalog to Database per connectionstrings.com.
<!--<add name="DefaultConnection" connectionString="Data Source=.\SQLEXPRESS;Initial Catalog=MVCTesting;Integrated Security=False;User Id=Green;Password=******" providerName="System.Data.SqlClient" />-->
<add name="DefaultConnection" connectionString="Data Source=.\SQLEXPRESS;Initial Catalog=MVCTesting;Integrated Security=True;" providerName="System.Data.SqlClient" />
I compared the SQL users MachineName/LoginName and Green. They both have server roles of public and sysadmin, neither have any user mappings till a db is created then they are mapped to that db.
In global.asax.cs I have
protected void Application_Start()
{
Database.SetInitializer(new MVCTestingInitializer());
//Database.SetInitializer(new DropCreateDatabaseAlways<MVCTestingContext>());
ViewDb();
//Other setup
}
//Init the db by looking up a contact
private void ViewDb()
{
using (var context = new MVCTestingContext())
{
var user = context.Contacts.Where(u => u.FirstName.StartsWith("T"));
var asdf = "";
}
}
And my initializer is ...
public class MVCTestingInitializer : DropCreateDatabaseAlways<MVCTestingContext>
{
protected override sealed void Seed(MVCTestingContext context)
{
//Code to init the db
}
}
Using NLog I am able to verify if the seed is run or not. When I have integrated security it runs, when I do not the seed does not run.
I have also created an account on the machine, added that account to the AppPool and SQL Server, then retested. I still see a failure to connect.
System.Data.SqlClient.SqlException: Login failed for user 'Green'.
In a mad fit I decided to add all possible permissions to the user 'Green', I still see the above error. Does anyone see what I am missing? I am sure it is so simple and I will smack myself in the head afterwards, but I just do not see it.
If I am really far off, please provide the steps to create a SQL Account/Permissions that I can use in my web config and please include app pool setup.
Thanks,
TJ
I will post it as answer :)
If you ever have problem with connecting to db, open ssms and use the same credentials to login to db. This will confirm you have right credentials ;)

Azure role configuration management

I don't see how Windows Azure lets you vary the configuration of an application when you have no choice but to hold configuration settings in web.config (or app.config).
For example...
Quite often projects will make use of a 3rd party library that makes heavy use of web.config. The use of web.config may involve connection strings, app settings or custom configuration sections. A good example of this is ELMAH. A web.config file for ELMAH might look like the following:
<configuration>
<configSections>
<sectionGroup name="elmah">
<section name="security" requirePermission="false" type="Elmah.SecuritySectionHandler, Elmah" />
<section name="errorLog" requirePermission="false" type="Elmah.ErrorLogSectionHandler, Elmah" />
</sectionGroup>
</configSections>
<connectionStrings>
<add
name="MyElmahDatabase"
providerName="System.Data.SqlClient"
connectionString="Server=tcp:myServer.database.windows.net,1433;Database=myDB;User ID=user#myServer;Password=password;Trusted_Connection=False;Encrypt=True;Connection Timeout=30" />
</connectionStrings>
<elmah>
<security allowRemoteAccess="1" />
<errorLog type="Elmah.SqlErrorLog, Elmah" connectionStringName="MyElmahDatabase" />
</elmah>
</configuration>
There are a couple of problems here:
There is no way for me to update or vary whether remote access is enabled between Service Configurations.
There is no way for me to update or vary the ELMAH connection string between Service Configurations.
This is because the web.config is packaged as is into the .cspkg file and ELMAH will not look at the Service Configuration settings (which are the only way I can vary configuration settings between Service Configurations).
I can think of many other examples where this is a problem...
Any data access frameworks that look directly at the connection strings section.
Any custom configuration settings I need to create.
...to name just two.
Am I missing something or is this a significant gap in the configuration management offered by Windows Azure?
EDIT
From the answer and comments below, it looks like this is something that is not well supported. I think that managing multiple solution build configurations to support different configuration profiles is a very weak solution. I should not have to rebuild the solution for each configuration profile I need (there will likely be quite a few). Compilation is not equal to configuration.
I was wondering if there was a way to modify the .cspkg file as it is just a zip file. According to this documentation you can on Linux.
I've looked at the manifest in the .cspkg file and it looks like this:
<PackageManifest version="2">
<Encryption keytype="1" />
<Contents hashtype="1">
<Item name="MyApp.Web.UI_<GUID>.cssx" hash="AED69299C5F89E060876BC16BD3D6DE5130F6E62FFD2B752BAF293435339B7E2" uri="/MyApp.Web.UI_<GUID>.cssx" />
<Item name="MyApp.Web.Services_<GUID>.cssx" hash="7AC81AFF642E4345173C8470C32A41118A4E3CFD4185B82D0ADA44B71057192D" uri="/MyApp.Web.Services_<GUID>.cssx" />
<Item name="SMPackage_<GUID>.csmx" hash="B5E6B83B62AF64C7C11CAC1A394ABBF15D7DB7667A773C5284CE5BE95C5834E9" uri="/SMPackage_<GUID>.csmx" />
<Item name="SDPackage_<GUID>.csdx" hash="F34B7C02A551D82BAD96881E2DA9447D0014D49B47CCB3840475BDC575234A7D" uri="/SDPackage_<GUID>.csdx" />
<Item name="NamedStreamPackage_<GUID>.csnsx" hash="FA2B5829FF5D9B2D69DCDDB0E5BDEE6B8B0BC09FFBF37DAEEE41CF3F3F4D0132" uri="/NamedStreamPackage_<GUID>.csnsx" />
</Contents>
<NamedStreams>
<Stream name="RequiredFeatures/MyApp.Web.Services/1.0" />
<Stream name="RequiredFeatures/MyApp.Web.UI/1.0" />
<Stream name="SupportData/MyApp.Web.Services/1.0" />
<Stream name="SupportData/MyApp.Web.UI/1.0" />
</NamedStreams>
</PackageManifest>
Unfortunately, if I re-compute the hash of the unchanged "MyApp.Web.UI_.cssx" file, my hash is different from the one in the manifest.
Hash from manifest: AED69299C5F89E060876BC16BD3D6DE5130F6E62FFD2B752BAF293435339B7E2
My calculated hash: E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855
Note that I have not yet changed the file, so the hash should be the same.
This suggests I'm calculating it wrong. My method was as follows:
class Program
{
static void Main(string[] args)
{
using (FileStream fs = new FileStream(args[0], FileMode.Open))
{
ComputeHash(new SHA256Managed(), fs);
}
}
private static void ComputeHash(HashAlgorithm hashAlgorithm, Stream stream)
{
byte[] hash = hashAlgorithm.ComputeHash(stream);
string hashString = BitConverter.ToString(hash);
Console.WriteLine(hashString.Replace("-", string.Empty));
Console.WriteLine();
}
}
The documentation link above, suggests it is straightforward to re-calculate the hash (on Linux anyway).
Does anyone know how to re-compute the hashes?
Passing a Stream to ComputeHash() ends up with a different hash as compared to using the byte[] overload. I don't know why.
Try something like:
private static void ComputeHash(HashAlgorithm hashAlgorithm, Stream stream)
{
BinaryReader reader = new BinaryReader(stream)
byte[] hash = hashAlgorithm.ComputeHash( reader.ReadBytes( (int)stream.Length ) );
string hashString = BitConverter.ToString(hash);
Console.WriteLine(hashString.Replace("-", string.Empty));
Console.WriteLine();
}
This will give you the hash you're after.
As you've probably already discovered, on linux you can get the digest with
openssl dgst -sha256 /path/to/file
I you have items in your web.config that you want to change depending on how it's being built, there is a solution that is outside of Azure that you can use. You can use Web.config transforms. These transforms are tied to your build configuration not your service configuration, but your service configurations a likely closely tied to your build configurations anyway (...Local.csfg -> Debug, ...Cloud.csfg -> Release). If the default build configurations don't work for you, just create the ones you need.
If you want to use different service definitions per service configuration, then it's not supported by the UI, but you can mess around with the build process to make it work

Mvc-Mini-Profiler v1.7 on EF 4.1 Code-First project doesn't profile SQL

I setup MiniProfiler.MVC3 - 1.7 package in my project yesterday. The Controller and view profiling is working fine, but the peice I'm really interested in is the SQL Profiling. I have not been able to get this to work. I'm using EF Code First with a SQL 2008 database.
I have followed all the suggestions in this post ..
mvcminiprofiler-on-ef-4-1-code-first-project-doesnt-profile-sql
In the miniprofiler.cs i have my SQL connection setup as...
var factory = new SqlConnectionFactory(ConfigurationManager.ConnectionStrings["CMDBMVC3"].ConnectionString);
My Web.config db connection is...
<add name="CMDBMVC3" connectionString="data source=.\SQLEXPRESS;Integrated Security=SSPI; AttachDBFilename=|DataDirectory|CMDB_MVC3.mdf;Initial Catalog=CMDB_MVC3;Trusted_Connection=True;MultipleActiveResultSets=True" providerName="System.Data.SqlClient" />
If I put a breakpoint on the mini-profiler line it points to the correct db connection. I'm not sure what else to do at this point. I would appreciate any direction on how to get the SQL profiling working.
I use EF Code first and the mini profiler within my Context constructor I create a new connection factory and pass this to the ProfiledDbConnectionFactory method this returns a profiled connection that you can then set as the DefaultConnectionFactory of the context.
public MyConext()
{
var factory = new ConnectionFactory();
var profiled = new MvcMiniProfiler.Data.ProfiledDbConnectionFactory(factory);
Database.DefaultConnectionFactory = profiled;
}
The connection Facotry just returns a new sql connection
public class ConnectionFactory :IDbConnectionFactory
{
public DbConnection CreateConnection()
{
var cnn = new System.Data.SqlClient.SqlConnection(ConfigurationManager.ConnectionStrings["SomeConnection"].ToString());
return cnn;
}
You also need to add the ProfiledDBProvider to the web config file. Make sure the version number is correct for you.
<system.data>
<DbProviderFactories>
<remove invariant="MvcMiniProfiler.Data.ProfiledDbProvider" />
<add name="MvcMiniProfiler.Data.ProfiledDbProvider" invariant="MvcMiniProfiler.Data.ProfiledDbProvider"
description="MvcMiniProfiler.Data.ProfiledDbProvider"
type="MvcMiniProfiler.Data.ProfiledDbProviderFactory, MvcMiniProfiler, Version=1.7.0.0, Culture=neutral, PublicKeyToken=b44f9351044011a3" />
</DbProviderFactories>
</system.data>
This works fine for me in both MVC and asp.net webforms using the Miniprofiler nuget package. I'd also check out the new MVC version of the nuget package that auto configs profiling as part of a global action filter.