1、DbContext
由于自己时间关系直接贴上亲切的代码。代码也相对比较简单,比较清晰,就不做文字介绍。
public class AppDbContext : DbContext
{
public AppDbContext(DbContextOptions<AppDbContext> options) : base(options)
{
}
public DbSet<Users> Users { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
//optionsBuilder.UseSqlServer("Server=.;Database=EFCoreDemo;Trusted_Connection=True;");
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
#region global setting column type
var properties = modelBuilder.Model.GetEntityTypes()
.SelectMany(t => t.GetProperties());
var dateTypes = properties.Where(t => t.ClrType == typeof(DateTime) || t.ClrType == typeof(DateTime?));
var decimalTypes = properties.Where(t => t.ClrType == typeof(decimal) || t.ClrType == typeof(decimal?));
foreach (var property in dateTypes)
{
property.SetColumnType("datetime");
}
foreach (var property in decimalTypes)
{
property.SetPrecision(18);
property.SetScale(2);
}
#endregion
#region global setting filter
var methedInfo = typeof(AppDbContext)
.GetMethod(
nameof(ConfigureGlobalFilters),
BindingFlags.Instance | BindingFlags.NonPublic
);
foreach (var entityType in modelBuilder.Model.GetEntityTypes())
{
methedInfo.MakeGenericMethod(entityType.ClrType)
.Invoke(this, new object[] { modelBuilder, entityType });
}
#endregion
#region InitData
InitData(modelBuilder);
#endregion
}
protected virtual void ConfigureGlobalFilters<TEntity>(ModelBuilder modelBuilder, IMutableEntityType mutableEntityType)
where TEntity : class
{
if (mutableEntityType.BaseType == null)
{
var filterExpression = CreateFilterExpression<TEntity>();
if (filterExpression != null)
{
modelBuilder.Entity<TEntity>().HasQueryFilter(filterExpression);
}
}
}
protected virtual Expression<Func<TEntity, bool>> CreateFilterExpression<TEntity>()
where TEntity : class
{
Expression<Func<TEntity, bool>> expression = null;
if (typeof(ISoftDelete).IsAssignableFrom(typeof(TEntity)))
{
expression = e => !EF.Property<bool>(e, "IsDeleted");
}
return expression;
}
private void InitData(ModelBuilder modelBuilder)
{
int userId = 1;
modelBuilder.Entity<Users>().HasData(new[]
{
new Users
{
Id=userId++,
Weight=65.22m,
CreationTime=DateTime.Now
},
new Users
{
Id=userId++,
Weight=65.22m,
CreationTime=DateTime.Now,
UpdatedTime=DateTime.Now,
DeletedTime=DateTime.Now,
IsDeleted=true
}
});
}
}
2、Entity
public class Users : ISoftDelete
{
public int Id { get; set; }
public decimal Weight { get; set; }
public DateTime CreationTime { get; set; }
public DateTime? UpdatedTime { get; set; }
public bool? IsDeleted { get; set; }
public DateTime? DeletedTime { get; set; }
}
public interface ISoftDelete
{
public bool? IsDeleted { get; set; }
public DateTime? DeletedTime { get; set; }
}
3、Migration
dotnet ef migrations add Inital
dotnet ef database update
4、Testing
public class Program
{
public static void Main(string[] args)
=> CreateHostBuilder(args).Build().Run();
public static IHostBuilder CreateHostBuilder(string[] args)
=> Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(
webBuilder => webBuilder.UseStartup<Startup>());
}
public class Startup
{
public void ConfigureServices(IServiceCollection services)
=> services.AddDbContext<AppDbContext>(options => options.UseSqlServer("Server=.;Database=EFCoreDemo;Trusted_Connection=True;"));
public void Configure(IApplicationBuilder app, IWebHostEnvironment env, AppDbContext context)
{
void TestGlobalFilter()
{
// testing
var allUsers = context.Users.IgnoreQueryFilters().ToList();
Debug.Assert(allUsers.Count == 2);
var byFilterUsers = context.Users.ToList();
Debug.Assert(byFilterUsers.Count == 1);
};
TestGlobalFilter();
}
}