EF6 with MySQL. The given key was not present in the dictionary - mysql

I have Asp.Net MVC 5 application using Code First Entity Framework 6 linked to MySQL database.
When I created the database first time, it works fine. But when I make a change to the model then add migration. An error shows after (Update-Database).
This is the error:
PM> Update-Database
System.Collections.Generic.KeyNotFoundException: The given key was not present in the dictionary.
at System.Collections.Generic.Dictionary`2.get_Item(TKey key)
at MySql.Data.MySqlClient.MySqlConnectionStringBuilder.<>c.<.cctor>b__2_7(MySqlConnectionStringBuilder msb, MySqlConnectionStringOption sender)
at MySql.Data.MySqlClient.MySqlConnectionStringBuilder.get_Item(String keyword)
at MySql.Data.MySqlClient.MySqlConnectionStringBuilder.GetConnectionString(Boolean includePass)
at MySql.Data.MySqlClient.MySqlConnection.get_ConnectionString()
at System.Data.Entity.Infrastructure.Interception.DbConnectionDispatcher.<GetConnectionString>b__12(DbConnection t, DbConnectionInterceptionContext`1 c)
at System.Data.Entity.Infrastructure.Interception.InternalDispatcher`1.Dispatch[TTarget, TInterceptionContext, TResult](TTarget target, Func`3 operation, TInterceptionContext interceptionContext, Action`3 executing, Action`3 executed)
at System.Data.Entity.Infrastructure.Interception.DbConnectionDispatcher.GetConnectionString(DbConnection connection, DbInterceptionContext interceptionContext)
at System.Data.Entity.Internal.InternalConnection.GetStoreConnectionString(DbConnection connection)
at System.Data.Entity.Internal.InternalConnection.OnConnectionInitialized()
at System.Data.Entity.Internal.EagerInternalConnection..ctor(DbContext context, DbConnection existingConnection, Boolean connectionOwned)
at System.Data.Entity.DbContext..ctor(DbConnection existingConnection, Boolean contextOwnsConnection)
at System.Data.Entity.Migrations.History.HistoryContext..ctor(DbConnection existingConnection, String defaultSchema)
at MySql.Data.Entity.MySqlHistoryContext..ctor(DbConnection existingConnection, String defaultSchema)
at code_first_mysql.Migrations.Configuration.<>c.<.ctor>b__0_0(DbConnection conn, String schema) in C:\Users\User\Documents\Tree\New Backend\code first mysql\Migrations\Configuration.cs:line 16
at System.Data.Entity.Migrations.History.HistoryRepository.CreateContext(DbConnection connection, String schema)
at System.Data.Entity.Migrations.History.HistoryRepository.<GetUpgradeOperations>d__16.MoveNext()
at System.Linq.Enumerable.Any[TSource](IEnumerable`1 source)
at System.Data.Entity.Migrations.DbMigrator.UpdateInternal(String targetMigration)
at System.Data.Entity.Migrations.DbMigrator.<>c__DisplayClassc.<Update>b__b()
at System.Data.Entity.Migrations.Infrastructure.MigratorScriptingDecorator.EnsureDatabaseExists(Action mustSucceedToKeepDatabase)
at System.Data.Entity.Migrations.DbMigrator.Update(String targetMigration)
at System.Data.Entity.Migrations.Infrastructure.MigratorBase.Update(String targetMigration)
at System.Data.Entity.Migrations.Infrastructure.MigratorBase.Update(String targetMigration)
at System.Data.Entity.Migrations.Infrastructure.MigratorScriptingDecorator.ScriptUpdate(String sourceMigration, String targetMigration)
at System.Data.Entity.Migrations.Design.ToolingFacade.ScriptUpdateRunner.Run()
at System.AppDomain.DoCallBack(CrossAppDomainDelegate callBackDelegate)
at System.AppDomain.DoCallBack(CrossAppDomainDelegate callBackDelegate)
at System.Data.Entity.Migrations.Design.ToolingFacade.Run(BaseRunner runner)
at System.Data.Entity.Migrations.Design.ToolingFacade.ScriptUpdate(String sourceMigration, String targetMigration, Boolean force)
at System.Data.Entity.Migrations.UpdateDatabaseCommand.<>c__DisplayClass2.<.ctor>b__0()
at System.Data.Entity.Migrations.MigrationsDomainCommand.Execute(Action command)
The given key was not present in the dictionary.
These are my MySQL Configuration Classes:
internal sealed class Configuration : DbMigrationsConfiguration<ApplicationDbContext>
{
public Configuration()
{
AutomaticMigrationsEnabled = false;
SetSqlGenerator("MySql.Data.MySqlClient", new MySqlMigrationSqlGenerator());
SetHistoryContextFactory("MySql.Data.MySqlClient", (conn, schema) => new MySqlHistoryContext(conn, schema));
CodeGenerator = new MySqlMigrationCodeGenerator();
}
protected override void Seed(ApplicationDbContext context)
{}
}
public class MySqlConfiguration: DbConfiguration
{
public MySqlConfiguration()
{
SetHistoryContext("MySql.Data.MySqlClient", (conn, schema) => new MySqlHistoryContext(conn, schema));
}
}
public class MySqlHistoryContext : HistoryContext
{
public MySqlHistoryContext(DbConnection existingConnection, string defaultSchema) : base(existingConnection, defaultSchema)
{
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<HistoryRow>().Property(h => h.MigrationId).HasMaxLength(100).IsRequired();
modelBuilder.Entity<HistoryRow>().Property(h => h.ContextKey).HasMaxLength(200).IsRequired();
}
}
public class MySqlInitializer : IDatabaseInitializer<ApplicationDbContext>
{
public void InitializeDatabase(ApplicationDbContext context)
{
if (!context.Database.Exists())
{
// if database did not exist before - create it
context.Database.Create();
}
else
{
// query to check if MigrationHistory table is present in the database
var migrationHistoryTableExists = ((IObjectContextAdapter)context).ObjectContext.ExecuteStoreQuery<int>(
string.Format(
"SELECT COUNT(*) FROM information_schema.tables WHERE table_schema = '{0}' AND table_name = '__MigrationHistory'", "mydb"));
// if MigrationHistory table is not there (which is the case first time we run) - create it
if (migrationHistoryTableExists.FirstOrDefault() == 0)
{
context.Database.Delete();
context.Database.Create();
}
}
}
}

As you see from the first lines of the error,
MySql.Data.MySqlClient.MySqlConnectionStringBuilder.<>c.<.cctor>b__2_7(MySqlConnectionStringBuilder
msb, MySqlConnectionStringOption sender)
at MySql.Data.MySqlClient.MySqlConnectionStringBuilder.get_Item(String
keyword)
the error has to do with the ConnectionString. The problem is the ConnectionString contains keys that can't be read.
Try to clean up the ConnectionString so that it has only
server
user id
password
database
In my case, the ConnectionString had an extra key integrated security. When this was removed Update-Database started working fine. Depending on your case however, this might and might not be the key that caused the error.
So again my proposed and guaranteed solution, go through ConnectionString and simplify it so that it contains only the 4 keys mentioned above.

Bug 75172
It is a bug reported in version 6.9.4,but I review it in 6.9.11.

Don't apply the newest mysql tools
Close Visual studio 2017
Uninstall mysql-for-visualstudio 2.0.5 Then, install mysql-for-visualstudio 1.2.8
Uninstall mysql-connector-net-8.0.17 Then, install mysql-connector-net-6.9.10.
Find the mysql.data.dll, MySql.Data.Entity.EF6.dll in
%Program Files (x86)%\MySQL\MySQL Connector Net 6.9.10\Assemblies\v4.5
Add to reference
Open nuget in references, downgrade EntityFramework 6 to EntityFramework 5

This worked for me: Close your visual studio and
go to this folder
C:\Users[youruser]\AppData\Roaming\Microsoft\VisualStudio\16.0_befcda98\ServerExplorer
And then delete the file DefaultView.SEView
Open your visual studio and try again.

Related

Using Entityframework Core, how can I dynamically change the MySql database, I connect to, without changing the connection string?

I'm using Pomelo Entity framework core with MySqlConnector in my asp.net 5 app to connect to my MySql database - using custom DbContext classes. This normally works fine.
However, I have a need to connect to another database than the one in the connection string (for instance 'INFORMATION_SCHEMA').
I can of course change the connection string, replacing the database name, but:
That creates an extra connection pool - one per connection string!
I'm trying to avoid that - having only one connection pool per website.
I was messing around with 'SetDefaultSchema' and other attempts that all fail miserably.
How can I change the database name, the DbContext uses so I only have one connection pool and still each DbContext has its own database to connect to?
The solution is actually quite simple: Use connection interceptor (available from Entity Framework Core 3.0+).
The code below switches the database after the connection has been opened.
Now each DbContext class can use its own database and with only one connection pool in use.
First you create an interceptor class inherited from DbConnectionInterceptor. The constructor takes the database name, you want to switch to, as parameter:
using Microsoft.EntityFrameworkCore.Diagnostics;
using System.Data.Common;
using System.Threading.Tasks;
public class MySqlConnectionInterceptor : DbConnectionInterceptor
{
public MySqlConnectionInterceptor(string databaseName)
{
database = databaseName;
}
readonly string database;
public override void ConnectionOpened(DbConnection connection, ConnectionEndEventData eventData)
{
if (database != null)
{
connection.ChangeDatabase(database); // The 'magic' code
}
base.ConnectionOpened(connection, eventData);
}
public override async Task ConnectionOpenedAsync(DbConnection connection, ConnectionEndEventData eventData, CancellationToken cancellationToken = default)
{
if (database != null)
{
await connection.ChangeDatabaseAsync(database); // The 'magic' code
}
await base.ConnectionOpenedAsync(connection, eventData, cancellationToken);
}
}
Now all you have to is include one line in your DbContext class's OnConfiguring method:
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.AddInterceptors(new MySqlConnectionInterceptor("yourDatabase"));
}
Now the connection will switch to 'yourDatabase' database every time, it's opened.
And it will only use one connection pool (total)! That way the number of 'sleeping' connections are kept at a minimum.
This works because Pomelo Entity Framework Core always resets a connection before reusing it from the pool (unless you specifically sets 'Connectionreset=false' - which is bad anyway). It sets the database back to the one in the connection string, which you of course can override again).
Of course you don't have to hard code the database name. If you for instance use a base DbContext class, that your other DbContexts inherits from, you can create a constructor that takes the database name as parameter, like this:
public class BaseDbContext : DbContext
{
public BaseDbContext (string databaseName)
{
database = databaseName;
}
string database;
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.AddInterceptors(new MySqlConnectionInterceptor(database));
}
}
The code has been tested in Asp.Net 5+6 and .Net Windows Forms.

Gettting Unable to determine the provider name for connection with MySql

I am working with ASP.NET MVC4 and I am trying to move my data access layer to a separate project. Each user on my site gets their own database so I need to specify a different database in the connection string for each user. The way I am currently doing this is:
public TableDbContext GetTableDbContextForUser(string userName)
{
MySqlConnection connection = new MySqlConnection(getUserConnectionString(userName));
return new MySqlTableDbContext(connection);
}
private string getUserConnectionString(string userName)
{
ConnectionStringSettings csSettings = ConfigurationManager.ConnectionStrings["MySqlConnection"];
MySqlConnectionStringBuilder csBuilder = new MySqlConnectionStringBuilder(csSettings.ConnectionString);
csBuilder.Database += "_" + userName;
return csBuilder.GetConnectionString(true);
}
And my constructor:
public MySqlTableDbContext(MySqlConnection connection)
: base(connection, false) //Inherits from DbContext
{ }
And finally my connection string (this is in Web.config in my main project and App.config in my database project):
<connectionStrings>
<add name="MySqlConnection" providerName="MySql.Data.MySqlClient" connectionString="server=localhost;User Id=root;Persist Security Info=True;database=cybercomm;password=*;DefaultCommandTimeout=0;" />
</connectionStrings>
MySqlTableDbContext is in my Database project and I am trying to use it in my main project. It gets created just fine however when I call any method through it I get the following error:
System.NotSupportedException was unhandled by user code
HResult=-2146233067
Message=Unable to determine the provider name for connection of type 'MySql.Data.MySqlClient.MySqlConnection'.
Source=EntityFramework
StackTrace:
at System.Data.Entity.ModelConfiguration.Utilities.DbConnectionExtensions.GetProviderInvariantName(DbConnection connection)
at System.Data.Entity.Internal.InternalConnection.get_ProviderName()
at System.Data.Entity.Internal.LazyInternalContext.InitializeContext()
at System.Data.Entity.Internal.InternalContext.Initialize()
at System.Data.Entity.Internal.InternalContext.ExecuteSqlCommand(String sql, Object[] parameters)
at System.Data.Entity.Database.ExecuteSqlCommand(String sql, Object[] parameters)
at EPSCoR.Web.Database.Context.MySqlTableDbContext.DropTable(String table) in c:\Users\Devin\Documents\Visual Studio 2012\Projects\EPSCoR\Web\Database\Context\MySqlTableDbContext.cs:line 110
at EPSCoR.Web.App.Repositories.Basic.BasicTableRepo.Drop(String tableName) in c:\Users\Devin\Documents\Visual Studio 2012\Projects\EPSCoR\Web\App\Repositories\Basic\BasicTableRepo.cs:line 71
at EPSCoR.Web.App.Controllers.TableIndexController.Delete(Int32 id) in c:\Users\Devin\Documents\Visual Studio 2012\Projects\EPSCoR\Web\App\Controllers\ModelController.cs:line 172
at lambda_method(Closure , ControllerBase , Object[] )
at System.Web.Mvc.ActionMethodDispatcher.Execute(ControllerBase controller, Object[] parameters)
at System.Web.Mvc.ReflectedActionDescriptor.Execute(ControllerContext controllerContext, IDictionary`2 parameters)
at System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary`2 parameters)
at System.Web.Mvc.Async.AsyncControllerActionInvoker.<>c__DisplayClass42.<BeginInvokeSynchronousActionMethod>b__41()
at System.Web.Mvc.Async.AsyncResultWrapper.<>c__DisplayClass8`1.<BeginSynchronous>b__7(IAsyncResult _)
at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResult`1.End()
at System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeActionMethod(IAsyncResult asyncResult)
at System.Web.Mvc.Async.AsyncControllerActionInvoker.<>c__DisplayClass37.<>c__DisplayClass39.<BeginInvokeActionMethodWithFilters>b__33()
at System.Web.Mvc.Async.AsyncControllerActionInvoker.<>c__DisplayClass4f.<InvokeActionMethodFilterAsynchronously>b__49()
I know that my connection string works because when I pass DbContext the connection name ("MySqlConnection") in the constructor I can update and create models. Its only when I try to change the database parameter in the string that it breaks. Also this worked when everything was in one project, so I know that this should work somehow.
Is there anything I am missing here?
In case it might help I have MySql.Data v6.7.4.0 and EF v5 installed through nuget.
I do not know why this worked but I reinstalled both the EntityFramework and MySql.Data packages and then everything started working again.

MySql 5 & LINQ to Entities EF 4 causing "Object must implement IConvertible" when querying across network

When using the same MVC 3 & C# code along with copies of the same MySql 5.5 database on 2 different MySql installations. One works perfectly while the other one fails with an "Object must implement IConvertible" error. When I run the query against my local PC's MySql installation the query always works perfectly, but when I try querying from local PC's Visual Studio 2010 to a copy of the same database at my Internet Service Provider's MySql installation then I receive an error "Object must implement IConvertible". The only thing I change in the code is the ConnectionString's Server Name in the web.config, otherwise the code & database are exactly the same. NOTE: All other queries to the ISP's MySql installation work perfectly only this one particular query doesn't work.
After trying to troubleshoot this for several days I'm convinced that the error message "Object must implement IConvertible" has nothing to do with what is actually happening and I'm also under the impression that the MySql configuration at my ISP may somehow be causing this issue for the following reasons:
If this were truly an "Object must implement IConvertible" issue within the code then the issue would persist in the code and happen no matter which DB installation I hit.
I've completely dropped & recreated the DB at the ISP from my local PC's working copy however still receive the same exactly error.
MOST INTERESTINGLY is that the query has 3 nested IEnumerable lists that are all setup in the same way as IEnumerables and if I comment out any 1 of these nested lists in the query then the query runs successfully against the ISP's DB. It doesn’t matter which nested list gets commented out, only that there are 2 or less nested lists and then the query to the DB at ISP works. This is what leads me to the conclusion that MySql’s configuration at the ISP may be limiting my queries in some way, as I do not have this problem when querying my local PC's MySql installation. The error message really doesn’t appear to apply to what is actually happening. Again, all the other queries to the ISP's MySql installation work perfectly, however none of them contain more than 2 nested IEnumerable lists where this particular query contains 3?
Query Error "Object must implement IConvertible"
Server Error in '/' Application.
________________________________________
Object must implement IConvertible.
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
Exception Details: System.InvalidCastException: Object must implement IConvertible.
Source Error:
Line 392:
Line 393:
Line 394: var query =
Line 395: (from p in db.products
Line 396: where p.ClientId == clientId
Source File: C:\Users\JR\Documents\Visual Studio 2010\Projects\Subversion\ReservarMVC\ReservarMVC\Models\ProductRepository.cs Line: 394
Stack Trace:
[InvalidCastException: Object must implement IConvertible.]
System.Convert.ChangeType(Object value, Type conversionType, IFormatProvider provider) +9528453
MySql.Data.Entity.EFMySqlDataReader.ChangeType(Object sourceValue, Type targetType) +566
MySql.Data.Entity.EFMySqlDataReader.GetValue(Int32 ordinal) +231
System.Data.Common.Internal.Materialization.ErrorHandlingValueReader`1.GetValue(DbDataReader reader, Int32 ordinal) +215
System.Data.Common.Internal.Materialization.Shaper.GetColumnValueWithErrorHandling(Int32 ordinal) +46
lambda_method(Closure , Shaper ) +180
System.Data.Common.Internal.Materialization.Coordinator`1.ReadNextElement(Shaper shaper) +170
System.Data.Common.Internal.Materialization.RowNestedResultEnumerator.MoveNext() +235
System.Data.Common.Internal.Materialization.ObjectQueryNestedEnumerator.TryReadToNextElement() +49
System.Data.Common.Internal.Materialization.ObjectQueryNestedEnumerator.ReadElement() +29
System.Data.Common.Internal.Materialization.ObjectQueryNestedEnumerator.MoveNext() +68
System.Collections.Generic.List`1..ctor(IEnumerable`1 collection) +327
System.Linq.Enumerable.ToList(IEnumerable`1 source) +58
ReservarMVC.Models.ProductRepository.GetProductList(Nullable`1 dateStart, Nullable`1 dateEnd, Nullable`1 personQuantityId, Nullable`1 roomQuantityId) in C:\Users\JR\Documents \Visual Studio 2010\Projects\Subversion\ReservarMVC\ReservarMVC\Models\ProductRepository.cs:394
ReservarMVC.Models.ProductRepository.GetProductListSearch(Nullable`1 dateStart, Nullable`1 dateEnd, Nullable`1 personQuantityId, Nullable`1 roomQuantityId) in C:\Users\JR\Documents\Visual Studio 2010\Projects\Subversion\ReservarMVC\ReservarMVC\Models\ProductRepository.cs:605
ReservarMVC.Controllers.PortalController.MyExcurcion(ProductListSearchVM viewModel) in C:\Users\JR\Documents\Visual Studio 2010\Projects\Subversion\ReservarMVC\ReservarMVC\Controllers\PortalController.cs:63
lambda_method(Closure , ControllerBase , Object[] ) +162
System.Web.Mvc.ActionMethodDispatcher.Execute(ControllerBase controller, Object[] parameters) +17
System.Web.Mvc.ReflectedActionDescriptor.Execute(ControllerContext controllerContext, IDictionary`2 parameters) +208
System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary`2 parameters) +27
System.Web.Mvc.<>c__DisplayClass15.<InvokeActionMethodWithFilters>b__12() +55
System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodFilter(IActionFilter filter, ActionExecutingContext preContext, Func`1 continuation) +263
System.Web.Mvc.<>c__DisplayClass17.<InvokeActionMethodWithFilters>b__14() +19
System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodWithFilters(ControllerContext controllerContext, IList`1 filters, ActionDescriptor actionDescriptor, IDictionary`2 parameters) +191
System.Web.Mvc.ControllerActionInvoker.InvokeAction(ControllerContext controllerContext, String actionName) +343
System.Web.Mvc.Controller.ExecuteCore() +116
System.Web.Mvc.ControllerBase.Execute(RequestContext requestContext) +97
System.Web.Mvc.ControllerBase.System.Web.Mvc.IController.Execute(RequestContext requestContext) +10
System.Web.Mvc.<>c__DisplayClassb.<BeginProcessRequest>b__5() +37
System.Web.Mvc.Async.<>c__DisplayClass1.<MakeVoidDelegate>b__0() +21
System.Web.Mvc.Async.<>c__DisplayClass8`1.<BeginSynchronous>b__7(IAsyncResult _) +12
System.Web.Mvc.Async.WrappedAsyncResult`1.End() +62
System.Web.Mvc.<>c__DisplayClasse.<EndProcessRequest>b__d() +50
System.Web.Mvc.SecurityUtil.<GetCallInAppTrustThunk>b__0(Action f) +7
System.Web.Mvc.SecurityUtil.ProcessInApplicationTrust(Action action) +22
System.Web.Mvc.MvcHandler.EndProcessRequest(IAsyncResult asyncResult) +60
System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.EndProcessRequest(IAsyncResult result) +9
System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +8967601
System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +184
________________________________________
Version Information: Microsoft .NET Framework Version:4.0.30319; ASP.NET Version:4.0.30319.261
LINQ-to-Entities Query:
public IEnumerable<ProductListVM> GetProductList(DateTime? dateStart, DateTime? dateEnd, int? personQuantityId, int? roomQuantityId)
{
var query =
(from p in db.products
where p.ClientId == clientId
where p.ProductTypeId == 5
where personQuantityId <= p.Capacity
where roomQuantityId <= p.Quantity
select new ProductListVM
{
ProductId = p.ProductId,
ClientId = p.ClientId,
Name = p.Name_en,
Title = p.Title_en,
Description = p.Description_en,
Quantity = p.Quantity,
Capacity = p.Capacity,
newbookings = from b in db.bookings
where b.ProductId == p.ProductId
from res in db.reservations
where b.ReseravationId == res.ReservationId
where b.BookingDateTime >= dateStart && b.BookingDateTime <= dateEnd && res.ReservationStateId != 3
select new BookingVM
{
ProductId = b.ProductId,
BookingId = b.BookingId,
ClientId = b.ClientId,
ReservationId = b.ReseravationId,
BookingDateTime = b.BookingDateTime
},
newratecategories = from prc in db.productratecategories
where prc.ProductId == p.ProductId
from rc in db.ratecategories
where prc.RateCategoryId == rc.RateCategoryId
where (dateStart >= rc.DateStart && dateEnd <= rc.DateEnd) || (dateStart >= rc.DateStart || dateEnd <= rc.DateEnd)
select new MegaRateCategoryVM
{
RateCategoryId = rc.RateCategoryId,
DateStart = rc.DateStart,
DateEnd = rc.DateEnd
},
newproductimages = (from pi in db.productimages
where pi.ProductId == p.ProductId
from ig in db.imagegalleries
where pi.ImageGalleryId == ig.ImageGalleryId
select new MegaProductImageVM
{
ig_Description = ig.ig_Description,
ImageGalleryId = pi.ImageGalleryId
}).OrderByDescending(i => i.ImageGalleryId)
}).ToList();
return query;
}
Product List ViewModel:
namespace Project.ViewModels
{
[Serializable]
public class ProductListVM : BaseViewModel
{
public int ProductId { get; set; }
public int? ClientId { get; set; }
public int? ProductTypeId { get; set; }
public int? ProductStateId { get; set; }
public String Name { get; set; }
public String Title { get; set; }
public String Description { get; set; }
public int? Quantity { get; set; }
public int? Capacity { get; set; }
//PRODUCTIMAGE table fields
public IEnumerable<MegaProductImageVM> newproductimages { get; set; }
//RATECATEGORY table fields
public IEnumerable<MegaRateCategoryVM> newratecategories { get; set; }
//BOOKING table fields
public IEnumerable<BookingVM> newbookings { get; set; }
}
}
What could be causing this behavior? Could this be caused by a query threshold setting or network setting on the MySql 5.5's database configuration? I haven't changed any of the defaults on either of the MySql 5.5 installations. I'm just using the standard MySql Connector/Net 6.5.4 to access the DB along with Microsoft's standard MVC 3, C#, Entity Framework 4, LINQ-to-Entities code.
Any help on this is greatly appreciated. Thanks, Atlas361
To fix this, add 'respect binary flags=false' to your connection string, e.g.:
connectionString="metadata=res://*/Something.csdl|res://*/Something.ssdl|
res://*/Something.msl;provider=MySql.Data.MySqlClient;
provider connection string="server=my-server;User Id=some-user;
Persist Security Info=True;database=some-database;respect binary flags=false""
This is a known issue with certain versions of MySQL 5.0 and 5.1
There are certain situations where MySQL will return incorrect metadata about one or more columns... In the event that the changes required to your application would be too large, adding 'respect binary flags=false' to your connection string causes the connector to use the prior behavior: any column that is marked as string, regardless of binary flags, will be returned as string. Only columns that are specifically marked as a BLOB will be returned as BLOB.
Hope this helps future travelers.
I published my MVC application to the ISP so that any potential issue caused by querying across the internet was eliminated but I still had the same exact error "Object must implement IConvertible”. After troubleshooting this further with the completely inept support staff at Arvixe.com I discovered that the actual version of MySql they had the database on was 5.1.54 released 2008 and not MySql 5.5 that was released in late 2010. According to the MySql documentation the MySql Connector/Net 6.5.4 & Microsoft's Entity Framework 4 are compatible, but I found this not to be true. After fighting with Arvixe.com to put me on MySql 5.5 server the problem went away. So in the end this was version compatibility issue.
Hope the answer helps! Atlas361

How to use a singleton for storing the RedisConnection with Booksleeve?

I'm using Booksleeve 1.1.0.6 (the latest nuget package).
I want so use a single connection for my whole Web Application so I'm storing it in a singleton:
public static RedisConnection Conn = RedisConfig.GetUnsecuredConnection(waitForOpen: true);
The RedisConfig.GetUnsecuredConnection method is the same as used in BookSleeve tests.
When I try to do an operation I get an InvalidOperationException: The queue is closed exception:
[InvalidOperationException: The queue is closed]
BookSleeve.MessageQueue.Enqueue(RedisMessage item, Boolean highPri) in C:\Dev\BookSleeve\BookSleeve\MessageQueue.cs:73
BookSleeve.RedisConnectionBase.ExecuteVoid(RedisMessage message, Boolean queueJump) in C:\Dev\BookSleeve\BookSleeve\RedisConnectionBase.cs:794
ASP.welisten_booksleevetests_aspx.SaveDictionaryToRedis(Dictionary`2 dictionary) +173
ASP.welisten_booksleevetests_aspx.Page_Load(Object sender, EventArgs e) +67
System.Web.Util.CalliHelper.EventArgFunctionCaller(IntPtr fp, Object o, Object t, EventArgs e) +25
System.Web.UI.Control.LoadRecursive() +71
System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +3064
I tried this with the waitForOpen parameter set to true and false
Here is the code I'm trying to execute:
private void SaveDictionaryToRedis(Dictionary<string, string> dictionary)
{
using (Mp.Step("Saving Data to Redis"))
{
using (RedisConfig.Conn)
{
RedisConfig.Conn.Strings.Set(DB, dictionary);
}
}
}
Depending on what was copied, it could be that there is a missing call to:
theConnection.Open();
which will open the connection and perform various handshakes. Thin the case of a singleton, this would be reasonable to do during the initializer.
However! Perhaps the problem here is that your second example is simply wrong. If Conn is, as described, a singleton - then it does not belong to that code, and you should not be using using. That would mean it is only usable once, and all subsequent access would fail. Just access the connection; no using here.

Entity Framework Code First - MySQL - error can't find table

I'm new to EF, EF Code First, and EF with MySQL. When would EF Code First create your tables within a ASP.NET MVC web project?
I created a Person model. Then generated the Controller and standard Views.
When I hit the Index method of the Person controller it tries to pull back a list of all People. Then I get the error:
An error occurred while executing the command definition. See the inner exception for details.
The inner exception:
Table 'testmvc.people' doesn't exist
So I've made it past the connection. But the table wasn't created. How do I create the tables? Also how do I prevent the pluralization of Person to People in the naming scheme?
The simplest way to generate the database schema (people table and others) is to set a database initializing strategy like this:
Database.SetInitializer<SomeContext>( new
DropCreateDatabaseAlways<SomeContext>());
This code needs to run before you attempt to load any data, so the Application_Start() method in Global.asax would be a good place to do that. There are several ways to initialize, so you may want to take a look at them before choosing one, see http://msdn.microsoft.com/en-us/library/system.data.entity%28v=vs.103%29.aspx and look at the methods that implement IDatabaseInitializer. Officially, there is a strategy by default, although I have never quite found that to work for me.
You should also be aware that while this method is great for prototyping and development, you can't quite use it on production database with live data since the database is first dropped and then recreated. There are other methods of doing this at that point - see Database migrations for Entity Framework 4 for possibilities.
Regarding your other question of using non-pluralized table names, there are several ways to do this. One way is to annotate the Person class like this:
[Table("Person")]
class Person
{
// some field attributes
}
To set this for all tables at once, you can use the fluent API, like this:
class SomeContext : DbContext
{
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
}
}
MySql with entity framework needs some little tweaks. You need to create three classes(you can check https://learn.microsoft.com/en-us/aspnet/identity/overview/getting-started/aspnet-identity-using-mysql-storage-with-an-entityframework-mysql-provider for more details). First create a MySqlHistoryContext class.
public class MySqlHistoryContext : HistoryContext
{
public MySqlHistoryContext(
DbConnection existingConnection,
string defaultSchema)
: base(existingConnection, defaultSchema)
{
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<HistoryRow>().Property(h =>
h.MigrationId).HasMaxLength(100).IsRequired();
modelBuilder.Entity<HistoryRow>().Property(h =>
h.ContextKey).HasMaxLength(200).IsRequired();
}
}
Create a MySqlConfiguration class next
public class MySqlConfiguration : DbConfiguration
{
public MySqlConfiguration()
{
SetHistoryContext(
"MySql.Data.MySqlClient", (conn, schema) => new MySqlHistoryContext(conn, schema));
}
}
Create MySqlInitializer class next
public class MySqlInitializer : IDatabaseInitializer<ApplicationDbContext>
{
public void InitializeDatabase(ApplicationDbContext context)
{
if (!context.Database.Exists())
{
// if database did not exist before - create it
context.Database.Create();
}
else
{
// query to check if MigrationHistory table is present in the database
var migrationHistoryTableExists =
((IObjectContextAdapter)context).ObjectContext.ExecuteStoreQuery<int>(
"SELECT COUNT(*) FROM information_schema.tables WHERE table_schema =
'IdentityMySQLDatabase' AND table_name = '__MigrationHistory'");
// if MigrationHistory table is not there (which is the case first time
we run) - create it
if (migrationHistoryTableExists.FirstOrDefault() == 0)
{
context.Database.Delete();
context.Database.Create();
}
}
}
}
Open the IdentityModels.cs in the model folder.Add this to the ApplicationDbContext : IdentityDbContext class
static ApplicationDbContext()
{
Database.SetInitializer(new MySqlInitializer());
}