此方法支持nopCommerce2.4以上版本(缺少的代码,可参照nopCommerce2.6源码)

nopCommerce 4.1 如何支持Mysql 请看 Url:  http://www.nopcn.com/nopcommerce-blog-95.html

在工程Easy.Data中:

1、添加MySqlConnectionFactory和MySqlDataProvider

在Easy.Data目录下添加两个Class,MySqlConnectionFactory和MySqlDataProvider,

MySqlConnectionFactory:

using MySql.Data.MySqlClient;
using System;
using System.Collections.Generic;
using System.Data.Common;
using System.Data.Entity.Infrastructure;
using System.Linq;
using System.Text; namespace Easy.Data
{
public class MySqlConnectionFactory : IDbConnectionFactory
{
private readonly string _baseConnectionString;
private Func<string, DbProviderFactory> _providerFactoryCreator; public MySqlConnectionFactory()
{
} public MySqlConnectionFactory(string baseConnectionString)
{
this._baseConnectionString = baseConnectionString;
} public DbConnection CreateConnection(string nameOrConnectionString)
{
string connectionString = nameOrConnectionString; bool treatAsConnectionString = nameOrConnectionString.IndexOf('=') >= ; if (!treatAsConnectionString)
{
MySqlConnectionStringBuilder builder = new MySqlConnectionStringBuilder(this.BaseConnectionString);
builder.Server = nameOrConnectionString;
connectionString = builder.ConnectionString;
}
DbConnection connection = null;
try
{
connection = this.ProviderFactory("MySql.Data.MySqlClient").CreateConnection();
connection.ConnectionString = connectionString;
}
catch
{
connection = new MySqlConnection(connectionString);
}
return connection;
} public string BaseConnectionString
{
get
{
return this._baseConnectionString;
}
} internal Func<string, DbProviderFactory> ProviderFactory
{
get
{
Func<string, DbProviderFactory> func1 = this._providerFactoryCreator;
return delegate(string name)
{
return DbProviderFactories.GetFactory(name);
};
}
set
{
this._providerFactoryCreator = value;
}
}
}
}

MySqlDataProvider:

using Easy.Data.Initializers;
using MySql.Data.MySqlClient;
using System;
using System.Collections.Generic;
using System.Data.Common;
using System.Data.Entity;
using System.Data.Entity.Infrastructure;
using System.IO;
using System.Linq;
using System.Text;
using System.Web.Hosting; namespace Easy.Data
{
public class MySqlDataProvider : BaseEfDataProvider
{
/// <summary>
/// Get connection factory
/// </summary>
/// <returns>Connection factory</returns>
public override IDbConnectionFactory GetConnectionFactory()
{
return new MySqlConnectionFactory();
} /// <summary>
/// Set database initializer
/// </summary>
public override void SetDatabaseInitializer()
{
//pass some table names to ensure that we have nopCommerce 2.X installed
var tablesToValidate = new[] { "Customer", "Discount", "Order", "Product", "ShoppingCartItem" }; //custom commands (stored proedures, indexes) var customCommands = new List<string>();
//use webHelper.MapPath instead of HostingEnvironment.MapPath which is not available in unit tests
customCommands.AddRange(ParseCommands(HostingEnvironment.MapPath("~/App_Data/MySql.Indexes.sql"), false));
//use webHelper.MapPath instead of HostingEnvironment.MapPath which is not available in unit tests
customCommands.AddRange(ParseCommands(HostingEnvironment.MapPath("~/App_Data/MySql.StoredProcedures.sql"), false)); var initializer = new CreateTablesIfNotExist<NopObjectContext>(tablesToValidate, customCommands.ToArray());
Database.SetInitializer(initializer);
} protected virtual string[] ParseCommands(string filePath, bool throwExceptionIfNonExists)
{
if (!File.Exists(filePath))
{
if (throwExceptionIfNonExists)
throw new ArgumentException(string.Format("Specified file doesn't exist - {0}", filePath));
else
return new string[];
} var statements = new List<string>();
using (var stream = File.OpenRead(filePath))
using (var reader = new StreamReader(stream))
{
var statement = "";
while ((statement = readNextStatementFromStream(reader)) != null)
{
statements.Add(statement);
}
} return statements.ToArray();
} protected virtual string readNextStatementFromStream(StreamReader reader)
{
var sb = new StringBuilder(); string lineOfText; while (true)
{
lineOfText = reader.ReadLine();
if (lineOfText == null)
{
if (sb.Length > )
return sb.ToString();
else
return null;
} //MySql doesn't support GO, so just use a commented out GO as the separator
if (lineOfText.TrimEnd().ToUpper() == "-- GO")
break; sb.Append(lineOfText + Environment.NewLine);
} return sb.ToString();
} /// <summary>
/// A value indicating whether this data provider supports stored procedures
/// </summary>
public override bool StoredProceduredSupported
{
get { return true; }
} /// <summary>
/// Gets a support database parameter object (used by stored procedures)
/// </summary>
/// <returns>Parameter</returns>
public override DbParameter GetParameter()
{
return new MySqlParameter();
}
}
}

2、在EfDataProviderManager.LoadDataProvider中添加一条case语句:

case "mysql":
return new MySqlDataProvider();

3、在Easy.Data.Initializers.CreateTablesIfNotExist中,对InitializeDatabase函数进行修改

将以下代码

if (dbExists)
{
bool createTables = false;
if (_tablesToValidate != null && _tablesToValidate.Length > )
{
//we have some table names to validate
var existingTableNames = new List<string>(context.Database.SqlQuery<string>("SELECT table_name FROM INFORMATION_SCHEMA.TABLES WHERE table_type = 'BASE TABLE'"));
createTables = existingTableNames.Intersect(_tablesToValidate, StringComparer.InvariantCultureIgnoreCase).Count() == ;
}
else
{
//check whether tables are already created
int numberOfTables = ;
foreach (var t1 in context.Database.SqlQuery<int>("SELECT COUNT(*) FROM INFORMATION_SCHEMA.TABLES WHERE table_type = 'BASE TABLE' "))
numberOfTables = t1; createTables = numberOfTables == ;
} if (createTables)
{
//create all tables
var dbCreationScript = ((IObjectContextAdapter)context).ObjectContext.CreateDatabaseScript();
context.Database.ExecuteSqlCommand(dbCreationScript); //Seed(context);
context.SaveChanges(); if (_customCommands != null && _customCommands.Length > )
{
foreach (var command in _customCommands)
context.Database.ExecuteSqlCommand(command);
}
}
}

修改至

if (dbExists)
{
string sql = string.Empty;
string countSql = string.Empty;
if (context.Database.Connection.GetType() == typeof(MySqlConnection))
{
sql = string.Format("SELECT table_name FROM INFORMATION_SCHEMA.TABLES WHERE table_type = 'BASE TABLE' AND table_schema = '{0}'", context.Database.Connection.Database);
countSql = string.Format("SELECT COUNT(*) FROM INFORMATION_SCHEMA.TABLES WHERE table_type = 'BASE TABLE' AND table_schema = '{0}'", context.Database.Connection.Database);
}
else
{
sql = @"SELECT table_name FROM INFORMATION_SCHEMA.TABLES WHERE table_type = 'BASE TABLE'";
countSql = @"SELECT COUNT(*) FROM INFORMATION_SCHEMA.TABLES WHERE table_type = 'BASE TABLE' ";
} bool createTables = false;
if (_tablesToValidate != null && _tablesToValidate.Length > )
{
//we have some table names to validate
var existingTableNames = new List<string>(context.Database.SqlQuery<string>(sql));
createTables = existingTableNames.Intersect(_tablesToValidate, StringComparer.InvariantCultureIgnoreCase).Count() == ;
}
else
{
//check whether tables are already created
int numberOfTables = ;
foreach (var t1 in context.Database.SqlQuery<int>(countSql))
numberOfTables = t1; createTables = numberOfTables == ;
} if (createTables)
{
//create all tables
var dbCreationScript = ((IObjectContextAdapter)context).ObjectContext.CreateDatabaseScript(); //Need to fix some of the script for MySql
if (context.Database.Connection.GetType() == typeof(MySqlConnection))
{
//MySql doesn't support varbinary(MAX) so it generates the script with varbinary only without
//a size specified, so change to longblob...could probably do this in the mapping for these properties instead
dbCreationScript = dbCreationScript.Replace("`PictureBinary` varbinary,", "`PictureBinary` LONGBLOB,");
dbCreationScript = dbCreationScript.Replace("`DownloadBinary` varbinary,", "`DownloadBinary` LONGBLOB,"); //Order is a keyword so need to put in quotes
dbCreationScript = dbCreationScript.Replace("REFERENCES Order (Id)", "REFERENCES `Order` (Id)"); //Some of the constraint names are too long for MySql, so shorten them
//dbCreationScript = dbCreationScript.Replace("ProductReview_TypeConstraint_From_CustomerContent_To_ProductReview", "ProductReview_CustomerContent_ProductReview");
//dbCreationScript = dbCreationScript.Replace("PollVotingRecord_TypeConstraint_From_CustomerContent_To_PollVotingRecord", "PollVotingRecord_CustomerContent_PollVotingRecord");
//dbCreationScript = dbCreationScript.Replace("ProductReviewHelpfulness_TypeConstraint_From_CustomerContent_To_ProductReviewHelpfulness", "ProductReviewHelpfulnes_CustomerContent_ProductReviewHelpfulnes");
} context.Database.ExecuteSqlCommand(dbCreationScript); //Seed(context);
context.SaveChanges(); if (_customCommands != null && _customCommands.Length > )
{
foreach (var command in _customCommands)
context.Database.ExecuteSqlCommand(command);
}
}
}

4、在领域Model中,一些属性Mapping需要更改,因为MySQL将字符串创建成Text/MediumText/LongText,而这些格式不支持索引,所以需要将这些Mapping修改成varchar,如将

this.Property(u => u.Username).HasMaxLength();
this.Property(u => u.Email).HasMaxLength();

修改成

this.Property(u => u.Username).HasMaxLength().HasColumnType("varchar");
this.Property(u => u.Email).HasMaxLength().HasColumnType("varchar");

5、最后,在Easy.Web.Models.Install.InstallModel中添加MySQL相关属性

//MySql properties
public string MySqlConnectionInfo { get; set; }
[AllowHtml]
public string MySqlServerName { get; set; }
[AllowHtml]
public string MySqlDatabaseName { get; set; }
[AllowHtml]
public string MySqlUsername { get; set; }
[AllowHtml]
public string MySqlPassword { get; set; }
public bool MySqlServerCreateDatabase { get; set; }
[AllowHtml]
public string MySqlDatabaseConnectionString { get; set; }

然后,在Easy.Web.Controllers.InstallController中添加MySQL相关的函数

private bool mySqlDatabaseExists(string connectionString)
{
try
{
//just try to connect
using (var conn = new MySqlConnection(connectionString))
{
conn.Open();
}
return true;
}
catch
{
return false;
}
} private string createMySqlDatabase(string connectionString)
{
try
{
//parse database name
var builder = new MySqlConnectionStringBuilder(connectionString);
var databaseName = builder.Database;
//now create connection string to 'master' dabatase. It always exists.
builder.Database = string.Empty; // = "master";
var masterCatalogConnectionString = builder.ToString();
string query = string.Format("CREATE DATABASE {0} COLLATE utf8_unicode_ci", databaseName); using (var conn = new MySqlConnection(masterCatalogConnectionString))
{
conn.Open();
using (var command = new MySqlCommand(query, conn))
{
command.ExecuteNonQuery();
}
} return string.Empty;
}
catch (Exception ex)
{
return string.Format("An error occured when creating database: {0}", ex.Message);
}
} private string createMySqlConnectionString(string serverName, string databaseName, string userName, string password, UInt32 timeout = )
{
var builder = new MySqlConnectionStringBuilder();
builder.Server = serverName;
builder.Database = databaseName.ToLower();
builder.UserID = userName;
builder.Password = password;
builder.PersistSecurityInfo = false;
builder.AllowUserVariables = true;
builder.DefaultCommandTimeout = ; builder.ConnectionTimeout = timeout;
return builder.ConnectionString;
}

最后,在Easy.Web.Views.Install.Index.cshtml中,添加MySQL的用户交互界面即可。

参考地址:http://www.nopcn.com/nopcommerce-detail-attr-course-2.html

nopCommerce如何支持MySQL的更多相关文章

  1. EntityFramework.Extended 支持 MySql

    EntityFramework.Extended 默认不支持 MySql,需要配置如下代码: [DbConfigurationType(typeof(DbContextConfiguration))] ...

  2. .NET高性能框架Chloe.ORM-完美支持MySql

    扯淡 这是一款轻量.高效的.NET C#数据库访问框架(ORM).查询接口借鉴 Linq(但不支持 Linq).借助 lambda 表达式,可以完全用面向对象的方式就能轻松执行多表连接查询.分组查询. ...

  3. oracle数据库不支持mysql中limit功能

    oracle数据库不支持mysql中limit功能,但可以通过rownum来限制返回的结果集的行数,rownum并不是用户添加的字段,而是oracle系统自动添加的. (1)使查询结果最多返回前10行 ...

  4. 支持MySql的数据库自动分表工具DBShardTools发布

    支持MySql的数据库自动分表工具DBShardTools发布 前段时间参与了公司的一个项目,这个项目的特点是数据量.访问量都比较大,考虑使用数据库水平分表策略,Google了大半天,竟然没有找到分表 ...

  5. 《物联网框架ServerSuperIO教程》-19.设备驱动和OPC Client支持mysql、oracle、sqlite、sqlserver的持久化。v3.6.4版本发布

    19.设备驱动和OPC Client支持mysql.oracle.sqlite.sqlserver的持久化 19.1     概述 ServerSuperIO支持设备驱动和OPC Client采集的数 ...

  6. 编译GDAL支持MySQL

    GDAL支持MySQL需要MySQL的库才可以,编译很简单,修改nmake.opt文件中对应的MySQL的库的路径和lib即可. nmake.opt文件中397行左右,如下: # MySQL Libr ...

  7. 让EntityFramework.Extended支持MySql

    EF:Entity Framework EFEL:Entity Framework Extended Library EFEL5.0时代是不支持MySql的,现在升级到6.0之后,已经支持MySql了 ...

  8. Visual Studio2015 、2017中如何支持MYSQL数据源

    原文:Visual Studio2015 .2017中如何支持MYSQL数据源 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/ght886/arti ...

  9. 微软企业库支持 MySql

    微软企业库支持 MySql   三步让企业库支持 mysql 数据库 1.创建 MySqlDatabaseData 类 using Microsoft.Practices.EnterpriseLibr ...

随机推荐

  1. 【TED演讲】阿帕玛・饶:(幽默的高科技艺术)

    身为艺术家和TED Fellow的阿帕玛・饶对熟悉的事物以惊奇的幽默的方式进行再次想像.通过和索伦・普尔兹的合作,她创作出一系列高科技的艺术作品-一个会发邮件的打字机,一个让你在屏幕上消失而跟踪拍摄你 ...

  2. 【NOIP 2011】Mayan游戏(搜索+模拟)

    描述 Mayan puzzle是最近流行起来的一个游戏.游戏界面是一个7行5列的棋盘,上面堆放着一些方块,方块不能悬空堆放,即方块必须放在最下面一行,或者放在其他方块之上.**游戏通关是指在规定的步数 ...

  3. linux进程切换问题

    #define switch_to(prev,next,last) do { \ unsigned long esi,edi; \ asm volatile("pushfl\n\t" ...

  4. kuangbin专题十二 HDU1114 Piggy-Bank (完全背包)

    Piggy-Bank Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total ...

  5. SPI 实现原理及运用

    SPI原理 SPI的全名为Service Provider Interface.大多数开发人员可能不熟悉,因为这个是针对厂商或者插件的.在java.util.ServiceLoader的文档里有比较详 ...

  6. shell学习(12)- jq

    jq命令允许直接在命令行下对JSON进行操作,包括分片.过滤.转换等 ,jq是用C编写,没有运行时依赖,所以几乎可以运行在任何系统上.预编译的二进制文件可以直接在Linux.OS X和windows系 ...

  7. POJ1004 Financial Management

    题目来源:http://poj.org/problem?id=1004 题目大意: Larry今年毕业并找到了工作.他开始赚很多的钱,然而他似乎总觉得不够.Larry决定好好掌控他的资产,解决他的财务 ...

  8. 【笔记】MySQL的基础学习(二)

    [笔记]MySQL的基础学习(二) MySQL 老男孩  一 视图 视图其实就是给表起个别名 1.创建视图 格式:CREATE VIEW 视图名称 AS SQL语句 CREATE VIEW v1 AS ...

  9. sharepoint_study_9

    描述:sharepoint2013 网站修改导航条标题 SuiteBartext 图示: 解决: 管理员身份进sharepoint powershell ,依次敲入搞定1. $app = Get-SP ...

  10. 读经典——《CLR via C#》(Jeffrey Richter著) 笔记_new新建对象

    CLR使用 new 操作符来创建新对象,例如:Employee e=new Employee("Param1");  以下是 new  操作符所做的事情. 它计算类型及其所有基类型 ...