From 0caf19787812f7a3f8d9087ce2d1a300ce816d8f Mon Sep 17 00:00:00 2001 From: edison Date: Sat, 17 Nov 2018 14:45:39 +0800 Subject: [PATCH 1/2] Complete the MongoDB integration document. --- docs/zh-Hans/MongoDB.md | 232 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 231 insertions(+), 1 deletion(-) diff --git a/docs/zh-Hans/MongoDB.md b/docs/zh-Hans/MongoDB.md index 17a7e106de..64df7d180b 100644 --- a/docs/zh-Hans/MongoDB.md +++ b/docs/zh-Hans/MongoDB.md @@ -95,4 +95,234 @@ services.AddMongoDbContext(options => }); ``` -现在可以在你的服务中注入并使用`IRepository` 或 `IQueryableRepository`了. \ No newline at end of file +现在可以在你的服务中注入并使用`IRepository` 或 `IQueryableRepository`了.比如你有一个主键类型为`Guid`的`Book`实体: + +```csharp +public class Book : AggregateRoot +{ + public string Name { get; set; } + + public BookType Type { get; set; } +} +``` + +(`BookType`是个枚举)你想在[领域服务](Domain-Services.md)中创建一个`Book`实体: + +```csharp +public class BookManager : DomainService +{ + private readonly IRepository _bookRepository; + + public BookManager(IRepository bookRepository) //注入默认的仓储 + { + _bookRepository = bookRepository; + } + + public async Task CreateBook(string name, BookType type) + { + Check.NotNullOrWhiteSpace(name, nameof(name)); + + var book = new Book + { + Id = GuidGenerator.Create(), + Name = name, + Type = type + }; + + await _bookRepository.InsertAsync(book); + //使用仓储中的方法 + + return book; + } +} +``` + +这是一个使用`InsertAsync`方法将一个实体插入到数据库的例子. + +#### 添加自定义仓储 + +大多数情况下默认的泛型仓储已经足够用了(因为它们实现了`IQueryable`).然而,你可能需要创建自定义的仓库并添加自己的仓储方法. + +比如你想要通过books类型删除书籍.建议像下面这样为你的仓储定义一个接口: + +```csharp +public interface IBookRepository : IRepository +{ + Task DeleteBooksByType( + BookType type, + CancellationToken cancellationToken = default(CancellationToken) + ); +} +``` + +通常你希望从`IRepository`中继承标准的仓储方法.其实,你不必那么做.仓储接口定义在领域层,在数据层/基础设施层实现.([启动模板](https://abp.io/Templates)中的`MongoDB`项目) + +实现`IBookRepository`接口的例子: + +```csharp +public class BookRepository : + MongoDbRepository, + IBookRepository +{ + public BookRepository(IMongoDbContextProvider dbContextProvider) + : base(dbContextProvider) + { + } + + public async Task DeleteBooksByType( + BookType type, + CancellationToken cancellationToken = default(CancellationToken)) + { + await Collection.DeleteManyAsync( + Builders.Filter.Eq(b => b.Type, type), + cancellationToken + ); + } +} +``` + +现在,就能在需要的时候[注入](Dependency-Injection.md)`IBookRepository`并使用`DeleteBooksByType`方法了. + +##### 重写默认的泛型仓储 + +即使你创建了自定义仓储,你仍然可以注入默认的泛型仓储(本例中的`IRepository`).默认的仓储实现不会使用你创建的类. + +如果你想用自定义的仓储替换默认的仓储实现,在`AddMongoDbContext`中做: + +```csharp +context.Services.AddMongoDbContext(options => +{ + options.AddDefaultRepositories(); + options.AddRepository(); //替换 IRepository +}); +``` + +当你想**重写基础仓储方法**时,这一点尤为重要.例如,你想要重写`DeleteAsync`方法,以便更有效的删除实体: + +```csharp +public override async Task DeleteAsync( + Guid id, + bool autoSave = false, + CancellationToken cancellationToken = default) +{ + //TODO: 自定义实现删除方法 +} +``` + +#### 访问MongoDB API + +大多数情况下,你想要将MongoDB API隐藏在仓储后面(这是仓储的主要目的).如果你想在仓储之上访问MongoDB API,你可以使用`GetDatabase()`或`GetCollection()`方法.例如: + +```csharp +public class BookService +{ + private readonly IRepository _bookRepository; + + public BookService(IRepository bookRepository) + { + _bookRepository = bookRepository; + } + + public void Foo() + { + IMongoDatabase database = _bookRepository.GetDatabase(); + IMongoCollection books = _bookRepository.GetCollection(); + } +} +``` + +> 重要:如果你想访问MongoDB API,你需要在你的项目中引用`Volo.Abp.MongoDB`.这会破坏封装,但在这种情况下,这就是你想要的. + +#### 高级主题 + +##### 设置默认的仓储类 + +默认的泛型仓储默认被`MongoDbRepository`类实现.你可以创建自己的实现并在默认的仓储中使用. + +首先,像下面这样定义你的仓储类: + +```csharp +public class MyRepositoryBase + : MongoDbRepository + where TEntity : class, IEntity +{ + public MyRepositoryBase(IMongoDbContextProvider dbContextProvider) + : base(dbContextProvider) + { + } +} + +public class MyRepositoryBase + : MongoDbRepository + where TEntity : class, IEntity +{ + public MyRepositoryBase(IMongoDbContextProvider dbContextProvider) + : base(dbContextProvider) + { + } +} +``` + +第一个是[复合主键的实体](Entities.md),第二个是只有一个主键的实体. + +如果需要重写方法建议继承`MongoDbRepository`类,否则,你需要手动实现所有的仓储方法. + +现在,你可以使用`SetDefaultRepositoryClasses`: + +```csharp +context.Services.AddMongoDbContext(options => +{ + options.SetDefaultRepositoryClasses( + typeof(MyRepositoryBase<,>), + typeof(MyRepositoryBase<>) + ); + //... +}); +``` + +##### 为默认的仓储设置基类或接口 + +如果你的MongoDbContext继承自另一个MongoDbContext或者实现了某个接口,你可以使用这个基类或者接口作为默认仓储的类型.如: +```csharp +public interface IBookStoreMongoDbContext : IAbpMongoDbContext +{ + Collection Books { get; } +} +``` + +`IBookStoreMongoDbContext`被`BookStoreMongoDbContext`类实现.然后你就可以在`AddDefaultRepositories`中使用: + +```csharp +context.Services.AddMongoDbContext(options => +{ + options.AddDefaultRepositories(); + //... +}); +``` + +现在,你自定义的`BookRepository`类也可以使用`IBookStoreMongoDbContext`接口: + +```csharp +public class BookRepository + : MongoDbRepository, + IBookRepository +{ + //... +} +``` + +为MongoDbContext使用接口的优点就是它可以被另一个实现替换. + +##### 替换其他的DbContexts + +一旦你正确定义并为MongoDbContext使用了接口,其他的实现就可以使用`ReplaceDbContext`来替换: + +```csharp +context.Services.AddMongoDbContext(options => +{ + //... + options.ReplaceDbContext(); +}); +``` + +这个例子中,`OtherMongoDbContext`实现了`IBookStoreMongoDbContext`.这个特性允许你在发开的时候使用多个MongoDbContext(每个模块一个),但是运行的时候只能使有一个MongoDbContext(实现所有MongoDbContexts的所有接口) \ No newline at end of file From 394da4f48cb6a2d3cb8c9b58f225b53c30b52a85 Mon Sep 17 00:00:00 2001 From: maliming Date: Sun, 18 Nov 2018 14:02:03 +0800 Subject: [PATCH 2/2] Update Getting-Started-AspNetCore-Application.md --- docs/zh-Hans/Getting-Started-AspNetCore-Application.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/zh-Hans/Getting-Started-AspNetCore-Application.md b/docs/zh-Hans/Getting-Started-AspNetCore-Application.md index bb3a26e4a5..d0733bb140 100644 --- a/docs/zh-Hans/Getting-Started-AspNetCore-Application.md +++ b/docs/zh-Hans/Getting-Started-AspNetCore-Application.md @@ -1,6 +1,6 @@ ## 在AspNet Core MVC Web Application中使用ABP -本教程将介绍如何开始以最少的依赖关系开始使用ABP开发. You generally want to start with a ***[startup template](https://abp.io/Templates)*** +本教程将介绍如何开始以最少的依赖关系开始使用ABP开发. 通常情况下你需要下载一个 ***[启动模板](https://abp.io/Templates)*** @@ -158,4 +158,4 @@ services.AddApplication(options => ### 源码 -从[此处](../samples/BasicAspNetCoreApplication)获取本教程中创建的示例项目的源代码. \ No newline at end of file +从[此处](../samples/BasicAspNetCoreApplication)获取本教程中创建的示例项目的源代码.