1.先创建两个DbContext
using System;
using System.Data.Common;
using System.Data.Entity;
using System.Data.Entity.ModelConfiguration;
using System.Data.Entity.ModelConfiguration.Conventions;
using System.Linq;
using System.Reflection;
using Abp.EntityFramework;
namespace TestProject.EntityFramework
{
public class TestProjectDbContext : AbpDbContext
{
//TODO: Define an IDbSet for each Entity…
//Example:
//public virtual IDbSet<User> Users { get; set; }
/\* NOTE:
\* Setting "Default" to base class helps us when working migration commands on Package Manager Console.
\* But it may cause problems when working Migrate.exe of EF. If you will apply migrations on command line, do not
\* pass connection string name to base classes. ABP works either way.
\*/
public TestProjectDbContext()
: base("Default")
{
}
/\* NOTE:
\* This constructor is used by ABP to pass connection string defined in TestProjectDataModule.PreInitialize.
\* Notice that, actually you will not directly create an instance of TestProjectDbContext since ABP automatically handles it.
\*/
public TestProjectDbContext(string nameOrConnectionString)
: base(nameOrConnectionString)
{
}
//This constructor is used in tests
public TestProjectDbContext(DbConnection existingConnection)
: base(existingConnection, false)
{
}
public TestProjectDbContext(DbConnection existingConnection, bool contextOwnsConnection)
: base(existingConnection, contextOwnsConnection)
{
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
var typesRegister = Assembly.GetExecutingAssembly().GetTypes()
.Where(type => !(string.IsNullOrEmpty(type.Namespace))).Where(type => type.BaseType != null && type.BaseType.IsGenericType && type.BaseType.GetGenericTypeDefinition() == typeof(EntityTypeConfiguration<>));
foreach (var type in typesRegister)
{
dynamic configurationInstance = Activator.CreateInstance(type);
modelBuilder.Configurations.Add(configurationInstance);
}
//删除级联
modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention>();
base.OnModelCreating(modelBuilder);
}
}
}
下面是新建的上下文,新建的DbContext不能含有DbContext(string nameOrConnectionString)构造函数,否则会被默认的连接名注入。
using Abp.EntityFramework;
using System;
using System.Collections.Generic;
using System.Data.Common;
using System.Data.Entity;
using System.Data.Entity.ModelConfiguration;
using System.Data.Entity.ModelConfiguration.Conventions;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
namespace TestProject.EntityFramework
{
public class TestSecondDbContext : AbpDbContext
{
//TODO: Define an IDbSet for each Entity...
public DbSet<AuditLog> AuditLog { get; set; }
//Example:
//public virtual IDbSet<User> Users { get; set; }
/\* NOTE:
\* Setting "Default" to base class helps us when working migration commands on Package Manager Console.
\* But it may cause problems when working Migrate.exe of EF. If you will apply migrations on command line, do not
\* pass connection string name to base classes. ABP works either way.
\*/
public TestSecondDbContext()
: base("Second")
{
}
//This constructor is used in tests
public TestSecondDbContext(DbConnection existingConnection)
: base(existingConnection, false)
{
}
public TestSecondDbContext(DbConnection existingConnection, bool contextOwnsConnection)
: base(existingConnection, contextOwnsConnection)
{
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
var typesRegister = Assembly.GetExecutingAssembly().GetTypes()
.Where(type => !(string.IsNullOrEmpty(type.Namespace))).Where(type => type.BaseType != null && type.BaseType.IsGenericType && type.BaseType.GetGenericTypeDefinition() == typeof(EntityTypeConfiguration<>));
foreach (var type in typesRegister)
{
dynamic configurationInstance = Activator.CreateInstance(type);
modelBuilder.Configurations.Add(configurationInstance);
}
//删除级联
modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention>();
base.OnModelCreating(modelBuilder);
}
}
}
2.创建实体类并且配置映射
public class AuditLogMap : EntityTypeConfiguration
{
public AuditLogMap()
{
ToTable("AuditLog");
HasKey(t => t.Id);
Property(t => t.BrowserInfo).IsOptional().HasColumnType("varchar").HasMaxLength();
Property(t => t.ClientIpAddress).IsOptional().HasColumnType("nvarchar").HasMaxLength();
Property(t => t.ClientName).IsOptional().HasColumnType("varchar").HasMaxLength();
Property(t => t.CustomData).IsOptional().HasColumnType("varchar").HasMaxLength();
Property(t => t.Exception).IsOptional().HasColumnType("varchar").HasMaxLength();
Property(t => t.ExecutionDuration).IsOptional();
Property(t => t.ExecutionTime).IsOptional();
Property(t => t.MethodName).IsOptional().HasColumnType("varchar").HasMaxLength();
Property(t => t.Parameters).IsOptional().HasColumnType("nvarchar").HasMaxLength();
Property(t => t.ServiceName).IsOptional().HasColumnType("varchar").HasMaxLength();
}
}
public abstract class TestProjectRepositoryBase
where TEntity : class, IEntity
{
protected TestProjectRepositoryBase(IDbContextProvider
: base(dbContextProvider)
{
}
//add common methods for all repositories
}
public abstract class TestProjectRepositoryBase<TEntity> : TestProjectRepositoryBase<TEntity, int>
where TEntity : class, IEntity<int>
{
protected TestProjectRepositoryBase(IDbContextProvider<TestProjectDbContext> dbContextProvider)
: base(dbContextProvider)
{
}
//do not add any method here, add to the class above (since this inherits it)
}
public abstract class TestSecondRepositoryBase
where TEntity : class, IEntity
{
protected TestSecondRepositoryBase(IDbContextProvider
: base(dbContextProvider)
{
}
//add common methods for all repositories
}
public abstract class TestSecondRepositoryBase<TEntity> : TestSecondRepositoryBase<TEntity, int>
where TEntity : class, IEntity<int>
{
protected TestSecondRepositoryBase(IDbContextProvider<TestSecondDbContext> dbContextProvider)
: base(dbContextProvider)
{
}
//do not add any method here, add to the class above (since this inherits it)
}
3.执行命令
enable-migrations -ContextTypeName TestProjectDbContext -MigrationsDirectory Migrations
enable-migrations -ContextTypeName TestSecondDbContext -MigrationsDirectory MigrationsSecond
add-migration -ConfigurationTypeName TestProject.Migrations.Configuration "InitialCreate" "InitialCreate"
add-migration -ConfigurationTypeName TestProject.MigrationsSecond.Configuration "InitialCreate"
update-database -ConfigurationTypeName TestProject.Migrations.Configuration -verbose
update-database -ConfigurationTypeName TestProject.MigrationsSecond.Configuration -verbose
4 开启MSDTC
MSDTC(分布式交易协调器),协调跨多个数据库、消息队列、文件系统等资源管理器的事务。该服务的进程名为Msdtc.exe,该进程调用系统Microsoft Personal Web Server和Microsoft SQL Server。该服务用于管理多个服务器 .
位置:控制面板--管理工具--服务--Distributed Transaction Coordinator
依存关系:Remote Procedure Call(RPC)和Security Accounts Manager
建议:一般家用计算机涉及不到,除非你启用Message Queuing服务,可以停止。
解决办法: . 在windows控制面版-->管理工具-->服务-->Distributed Transaction Coordinator-->属性-->启动
.在CMD下运行"net start msdtc"开启服务后正常。
注:如果在第1步Distributed Transaction Coordinator 无法启动,则是因为丢失了日志文件,重新创建日志文件,再启动就行了。重新创建 MSDTC 日志,并重新启动服务的步骤如下:
() 单击"开始",单击"运行",输入 cmd 后按"确定"。
() 输入:msdtc -resetlog (注意运行此命令时,不要执行挂起的事务)
() 最后输入:net start msdtc 回车,搞定!
手机扫一扫
移动阅读更方便
你可能感兴趣的文章