有時候一個項目需要連接多個數據庫,以實現不同數據庫的數據在同個項目的共享。
1、在SQLServer新建一個數據庫,我這里新建的是TestDb,表為TestTable。
USE [TestDb] GO SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO CREATE TABLE [dbo].[TestTable]( [Id] [int] IDENTITY(1,1) NOT NULL, [Name] [nvarchar](255) NOT NULL, [CreatedOnUtc] [datetime] NULL, CONSTRAINT [PK_TestTable] PRIMARY KEY CLUSTERED ( [Id] ASC )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] ) ON [PRIMARY] GO
2、添加實體,在Nop.Core下的Domain添加一個文件夾OtherDb,在OtherDb添加一個TestTable類,繼承BaseEntity
TestTable:
namespace Nop.Core.Domain.OtherDb { public class TestTable : BaseEntity { public string Name { get; set; }
public DateTime CreatedOnUtc { get; set; } } }
3、添加映射,在Nop.Data下的Mapping添加一個OtherDb文件夾,在OtherDb添加一個TestTableMap映射類,繼承NopEntityTypeConfiguration< TestTable >
TestTableMap:
namespace Nop.Data.Mapping.OtherDb { public class TestTableMap : NopEntityTypeConfiguration<TestTable> { public TestTableMap() { ToTable("TestTable");
HasKey(t => t.Id);
Property(t => t.Name).IsRequired().HasMaxLength(255); } } }
4、添加新的DbContext,在Nop.Data添加一個OhterDb,里面添加一個OtherDbObjectContext類繼承DbContext和IDbContext,添加一個OtherDbEfStartUpTask繼承IStartTask
OtherDbObjectContext:
namespace Nop.Data.OtherDb { public class OtherDbObjectContext : DbContext, IDbContext { public OtherDbObjectContext(string nameOrConnectionString) : base(nameOrConnectionString) { } protected override void OnModelCreating(DbModelBuilder modelBuilder) { modelBuilder.Configurations.Add(new TestTableMap()); base.OnModelCreating(modelBuilder); } public string CreateDatabaseScript() { return ((IObjectContextAdapter)this).ObjectContext.CreateDatabaseScript(); } public new IDbSet<TEntity> Set<TEntity>() where TEntity : Core.BaseEntity { return base.Set<TEntity>(); } public IList<TEntity> ExecuteStoredProcedureList<TEntity>(string commandText, params object[] parameters) where TEntity : Core.BaseEntity, new() { throw new NotImplementedException(); } public IEnumerable<TElement> SqlQuery<TElement>(string sql, params object[] parameters) { throw new NotImplementedException(); } public int ExecuteSqlCommand(string sql, bool doNotEnsureTransaction = false, int? timeout = null, params object[] parameters) { throw new NotImplementedException(); }
public void Detach(object entity) { throw new NotImplementedException(); }
public bool ProxyCreationEnabled { get { return this.Configuration.ProxyCreationEnabled; } set { this.Configuration.ProxyCreationEnabled = value; } } public bool AutoDetectChangesEnabled { get { return this.Configuration.AutoDetectChangesEnabled; } set { this.Configuration.AutoDetectChangesEnabled = value; } } } }
OtherDbEfStartUpTask:
namespace Nop.Data.OtherDb { public class OtherDbEfStartUpTask : IStartupTask { public void Execute() { Database.SetInitializer<OtherDbObjectContext>(null); } public int Order { get { return -1000; } } }
}
5、添加新的數據庫連接字符串文本文件,用於連接TestDb數據庫,在Nop.Web下面的App_Data下面添加一個文本文件命名OtherDbSetting.txt里面添加連接字符串
DataProvider: sqlserver
DataConnectionString: Data Source=.;Initial Catalog=TestDb;Integrated Security=False;Persist Security Info=False;User ID=登陸身份;Password=登陸密碼
改變數據庫連接名即可
6、在autofac注入新的OtherDbObjectContext,在Nop.WebFramework新建一個OtherDb文件夾,里面添加一個DependencyRegistrar類
DependencyRegistrar:
namespace Nop.Web.Framework.OtherDb { public class DependencyRegistrar : IDependencyRegistrar { protected virtual string MapPath(string path) { if (HostingEnvironment.IsHosted) { return HostingEnvironment.MapPath(path); } else { string baseDirectory = AppDomain.CurrentDomain.BaseDirectory; path = path.Replace("~/", "").TrimStart('/').Replace('/', '\\'); return Path.Combine(baseDirectory, path); } } public void Register(ContainerBuilder builder, Core.Infrastructure.ITypeFinder typeFinder, Core.Configuration.NopConfig config) { var dataSettingManager = new DataSettingsManager(); var dataProviderSettings = dataSettingManager.LoadSettings(Path.Combine(MapPath("~/App_Data/"), "OtherDbSetting.txt")); if (dataProviderSettings != null && dataProviderSettings.IsValid()) { builder.Register<IDbContext>(c => new OtherDbObjectContext(dataProviderSettings.DataConnectionString)) .Named<IDbContext>("nop_object_context_otherdb").InstancePerLifetimeScope(); //builder.Register<OtherDbObjectContext>( // c => new OtherDbObjectContext(dataProviderSettings.DataConnectionString)).InstancePerLifetimeScope(); } else { builder.Register<IDbContext>( c => new OtherDbObjectContext(c.Resolve<DataSettings>().DataConnectionString)).InstancePerLifetimeScope(); //builder.Register( // c => new OtherDbObjectContext(c.Resolve<DataSettings>().DataConnectionString)) // .InstancePerLifetimeScope(); } builder.RegisterType<EfRepository<TestTable>>() .As<IRepository<TestTable>>() .WithParameter(ResolvedParameter.ForNamed<IDbContext>("nop_object_context_otherdb")) .InstancePerLifetimeScope(); } public int Order { get { return -1; } } } }
全部添加沒問題后,添加其他業務實現代碼,重新生成解決方案即可。 此方案試用Nop3.4版本及以上,如有跟nop前期或者更新某個版本有差異,請自行斟酌修改。
如果你覺得對你有幫助,右側打個賞唄!
Author:黃仲秋
QQ:875755898