ASP.NET Zero全方位介绍

发布时间:2023-05-16

一、ASP.NET Zero 多表关联

ASP.NET Zero是一个基于ASP.NET Core的跨平台Web应用程序框架。在ASP.NET Zero中,我们可以非常方便地完成多表之间的关联操作。在实现多表之间的关联时,我们需要使用Entity Framework Core来设置各种实体之间的关系。

public class Order : FullAuditedAggregateRoot<long>
{
    [ForeignKey("Customer")]
    public long CustomerId { get; set; }
    public virtual Customer Customer { get; set; }
    [ForeignKey("Salesperson")]
    public long SalespersonId { get; set; }
    public virtual Salesperson Salesperson { get; set; }
}
public class Customer : FullAuditedAggregateRoot<long>
{
    public string Name { get; set; }
    public virtual ICollection<Order> Orders { get; set; }
}
public class Salesperson : FullAuditedAggregateRoot<long>
{
    public string Name { get; set; }
    public virtual ICollection<Order> Orders { get; set; }
}

在上述代码示例中,我们定义了三个实体,分别为Order、Customer和Salesperson。其中Order实体拥有一个外键关联到Customer实体和Salesperson实体。在Customer和Salesperson实体中,分别声明了与Order实体的导航属性。这样就完成了多表之间的关联配置。

二、ASP.NET Zero 10.4.0

ASP.NET Zero的10.4.0版本在原来的基础上增加了一些新的特性。其中比较重要的特性包括跨域请求、实现多语言支持以及实现分布式事务。 跨域请求是指在一个域名下的页面向另一个域名的页面发送请求的行为。在ASP.NET Zero中,我们可以使用CORS(跨域资源共享)来实现跨域请求。实现CORS的方式比较简单,只需在Startup.cs文件中的ConfigureServices方法中添加以下代码:

services.AddCors(options =>
{
    options.AddPolicy("AllowAll",
        builder => builder.AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader());
});
app.UseCors("AllowAll");

实现多语言支持是指在应用程序中可以动态更改用户的语言偏好设置。在ASP.NET Zero中,我们可以使用AspNetZeroLocalizationConfigurer来实现多语言支持。具体实现方式如下:

public override void ConfigureLocalizationService(ILocalizationServiceConfiguration localizationServiceConfiguration)
{
    localizationServiceConfiguration.DefaultResourceType = typeof(MyAppResource);
    localizationServiceConfiguration.Languages.Add(new LanguageInfo("en", "English", "famfamfam-flag-gb", isDefault: true));
    localizationServiceConfiguration.Languages.Add(new LanguageInfo("zh-Hans", "简体中文", "famfamfam-flag-cn"));
}

实现分布式事务是指在分布式环境下多个数据库之间进行数据交互时,可以保证数据的一致性。在ASP.NET Zero中,我们可以使用ABP框架自带的UnitOfWork来实现分布式事务。在代码中使用工作单元,如果抛出异常,则会自动回滚事务。

public class OrderAppService : MyProjectAppServiceBase, IOrderAppService
{
    private readonly IRepository<Order, long> _orderRepository;
    private readonly IRepository<Customer, long> _customerRepository;
    private readonly IRepository<Salesperson, long> _salespersonRepository;
    public OrderAppService(
        IRepository<Order, long> orderRepository,
        IRepository<Customer, long> customerRepository,
        IRepository<Salesperson, long> salespersonRepository)
    {
        _orderRepository = orderRepository;
        _customerRepository = customerRepository;
        _salespersonRepository = salespersonRepository;
    }
    public async Task CreateOrder(CreateOrderInput input)
    {
        using (var uow = UnitOfWorkManager.Begin())
        {
            try
            {
                // 创建订单
                var order = new Order
                {
                    CustomerId = input.CustomerId,
                    SalespersonId = input.SalespersonId,
                    CreationTime = Clock.Now
                };
                await _orderRepository.InsertAsync(order);
                // 修改客户信息
                var customer = await _customerRepository.GetAsync(input.CustomerId);
                customer.Name = input.CustomerName;
                await _customerRepository.UpdateAsync(customer);
                // 修改销售员信息
                var salesperson = await _salespersonRepository.GetAsync(input.SalespersonId);
                salesperson.Name = input.SalespersonName;
                await _salespersonRepository.UpdateAsync(salesperson);
                await uow.CompleteAsync();
            }
            catch (Exception)
            {
                await uow.RollbackAsync();
                throw;
            }
        }
    }
}

三、ASP.NET Zero连接两个数据库

ASP.NET Zero可以轻松地连接多个数据库。在连接多个数据库时,我们可以配置不同的DbContext。 我们可以使用ASP.NET Zero提供的ABP框架自带的DbContext来实现和使用不同的数据库。在配置多个DbContext时,需要在Startup.cs文件中的ConfigureServices方法中添加以下代码:

services.AddAbpDbContext<MyProjectDbContext>(options =>
{
    options.DbContextOptions.UseSqlServer(connectionStrings.Default);
});
services.AddAbpDbContext<OrderDbContext>(options =>
{
    options.DbContextOptions.UseSqlServer(connectionStrings.Order);
});

具体代码实现示例:

public class OrderDbContext : AbpDbContext<OrderDbContext>
{
    public OrderDbContext(DbContextOptions<OrderDbContext> options) : base(options)
    {
    }
    public DbSet<Order> Orders { get; set; }
    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);
        modelBuilder.ConfigureOrderStore();
    }
}
public static class OrderDbContextModelCreatingExtensions
{
    public static void ConfigureOrderStore(this ModelBuilder builder)
    {
        builder.Entity<Order>(b =>
        {
            b.ToTable("Orders");
            b.ConfigureByConvention();
        });
    }
}

在上述代码示例中,我们自定义了一个名为OrderDbContext的DbContext,并在其中定义了一个DbSet。我们还在ConfigureServices中将DbContext的配置细节添加了进去。 我们还可以在代码中使用连接另一个数据库来查询数据:

public async Task<IList<Order>> GetOrdersFromOtherDbContext(long customerId)
{
    using (var orderDbContext = _serviceProvider.GetService<OrderDbContext>())
    {
        return await orderDbContext.Orders
            .FromSqlRaw("SELECT * FROM Orders WHERE CustomerId = {0}", customerId)
            .ToListAsync();
    }
}

在上述代码示例中,我们在代码中使用了OrderDbContext来连接另一个数据库,并使用FromSqlRaw来执行查询,并得到了查询结果。