Couchbase의 새로운 EF 코어 공급자 는 기존에 관계형 데이터베이스에 묶여 있던 강력한 .NET 통합의 문을 열어줍니다. 이 게시물에서는 Identity, GraphQL 및 OData가 모두 Couchbase에서 어떻게 작동하는지 설명합니다.
이 게시물에서는 다음과 같이 안내해 드리겠습니다. 세 가지 고급 EF Core 통합 Couchbase로 성공적으로 테스트했습니다:
-
- ASP.NET 핵심 아이덴티티
- GraphQL(핫 초콜릿을 통한)
- OData
참고: 이러한 통합 기능은 제한된 테스트를 기반으로 하며 아직 공식적으로 지원되지 않습니다. 마일리지는 다를 수 있지만 지금까지는 많은 가능성을 보여주고 있습니다.
ASP.NET 핵심 아이덴티티
Microsoft.AspNetCore.Identity.EntityFrameworkCore 는 ASP.NET 앱을 위한 플러그 앤 플레이 인증 및 사용자 관리 시스템을 제공합니다.
Couchbase의 EF Core 제공업체가 잘 작동합니다. 한 가지 주의해야 할 점은 적절한 컬렉션이 먼저 존재합니다. (예: AspNetUsers, AspNetRoles 등).
참고: 다음 컬렉션을 미리 만들어야 합니다: AspNetUsers, AspNetRoles, AspNetUserRoles, AspNetUserClaims, AspNetUserLogins, AspNetUserTokens, AspNetRoleClaims.
EF 설정 예시
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
public class AppDbContext : IdentityDbContext<ApplicationUser> { public AppDbContext(DbContextOptions<AppDbContext> options) : base(options) { } protected override void OnModelCreating(ModelBuilder builder) { base.OnModelCreating(builder); builder.Entity<ApplicationUser>().ToCouchbaseCollection(this, "AspNetUsers"); builder.Entity<IdentityRole>().ToCouchbaseCollection(this, "AspNetRoles"); builder.Entity<IdentityUserRole<string>>().ToCouchbaseCollection(this, "AspNetUserRoles"); builder.Entity<IdentityUserClaim<string>>().ToCouchbaseCollection(this, "AspNetUserClaims"); builder.Entity<IdentityUserLogin<string>>().ToCouchbaseCollection(this, "AspNetUserLogins"); builder.Entity<IdentityUserToken<string>>().ToCouchbaseCollection(this, "AspNetUserTokens"); builder.Entity<IdentityRoleClaim<string>>().ToCouchbaseCollection(this, "AspNetRoleClaims"); } } public class ApplicationUser : IdentityUser { } |
MVC 인증 예제
다음은 등록, 로그인, 로그아웃 및 사용자 지정 역할이 있는 ASP.NET Core MVC 컨트롤러입니다:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 |
public class AuthController : Controller { private readonly UserManager<ApplicationUser> _userManager; private readonly SignInManager<ApplicationUser> _signInManager; private readonly RoleManager<IdentityRole> _roleManager; public AuthController(UserManager<ApplicationUser> userManager, SignInManager<ApplicationUser> signInManager, RoleManager<IdentityRole> roleManager) { _userManager = userManager; _signInManager = signInManager; _roleManager = roleManager; } public IActionResult Register() => View(); [HttpPost] public async Task<IActionResult> Register(RegisterModel model) { if (!ModelState.IsValid) return View(model); var user = new ApplicationUser { UserName = model.Email, Email = model.Email }; var result = await _userManager.CreateAsync(user, model.Password); if (result.Succeeded) { var roleName = "CustomRole"; if (!await _roleManager.RoleExistsAsync(roleName)) await _roleManager.CreateAsync(new IdentityRole(roleName)); await _userManager.AddToRoleAsync(user, roleName); await _signInManager.SignInAsync(user, isPersistent: false); return RedirectToAction("Index", "Home"); } foreach (var error in result.Errors) ModelState.AddModelError("", error.Description); return View(model); } public IActionResult Login() => View(); [HttpPost] public async Task<IActionResult> Login(LoginModel model) { if (!ModelState.IsValid) return View(model); var result = await _signInManager.PasswordSignInAsync(model.Email, model.Password, false, false); if (result.Succeeded) return RedirectToAction("Index", "Home"); ModelState.AddModelError("", "Invalid login attempt."); return View(model); } public async Task<IActionResult> Logout() { await _signInManager.SignOutAsync(); return RedirectToAction("Index", "Home"); } } |
데이터는 표준 ID 구조를 따르며, Couchbase 문서에 저장됩니다. 예를 들어 AspNetUser 컬렉션:

핫 초콜릿을 사용한 그래프QL
핫 초콜릿 는 널리 사용되는 .NET용 GraphQL 서버입니다. 이 서버는 공급자의 LINQ 기능(Couchbase가 제공하는 기능)을 활용하여 EF Core와 통합할 수 있습니다. 즉, GraphQL 쿼리가 LINQ로 변환된 다음 Couchbase SQL++로 변환됩니다.
설정
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
public class WidgetQuery { [UseFiltering] [UseSorting] public IQueryable<Widget> GetWidgets([Service] WidgetDbContext dbContext) => dbContext.Widgets; } // Program.cs: builder.Services .AddGraphQLServer() .AddQueryType<WidgetQuery>() .AddFiltering() .AddSorting() .AddProjections(); app.MapGraphQL(); |
사용 예
- 다음으로 이동 /graphql 을 클릭합니다(웹 인터페이스가 나타납니다).
- 다음과 같은 쿼리를 시도해 보세요:
|
1 2 3 4 5 6 7 8 9 |
query { widgets(where: { name: { contains: "foo" } }, order: { createdDt: DESC }) { id name price numInStock createdDt } } |
다음과 같은 결과가 반환됩니다:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 |
{ "data": { "widgets": [ { "id": "b5c494fe-135f-4f01-bf12-6e4ad1eee829", "name": "foobar", "price": 1.99, "numInStock": 50, "createdDt": "2025-06-18T18:11:19.149Z" } ] } } |
팁
-
- GraphQL 쿼리는 GSI 인덱스와 일치해야 합니다(내부적으로는 SQL++ 쿼리일 뿐입니다).
- 다음을 사용할 수 있습니다. 표지 인덱스 및 기타 SQL++ 인덱스를 사용하여 성능을 개선합니다.
OData
Microsoft.AspNetCore.OData 는 EF Core 데이터를 OData 엔드포인트로 노출하므로 Excel, Power BI, Tableau와 같은 도구를 Couchbase에 쉽게 연결할 수 있습니다.
프로그램.cs 샘플
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
builder.Services.AddControllersWithViews() .AddOData(opt => { var odataBuilder = new ODataConventionModelBuilder(); odataBuilder.EntitySet<Widget>("Widgets"); opt.AddRouteComponents("odata", odataBuilder.GetEdmModel()) .Filter() .OrderBy() .Select() .Expand() .Count() .SetMaxTop(100); }); |
컨트롤러
|
1 2 3 |
[HttpGet("/odata/Widgets")] [EnableQuery] public IQueryable<Widget> GetOData() => _context.Widgets; |
OData 쿼리 예제
-
- https://localhost:7037/odata/Widgets?$filter=price gt 1&$orderby=name
- https://localhost:7037/odata/Widgets?$select=name,price&$top=10

참고: EF Core LINQ 쿼리를 SQL++로 변환할 수 있는지, 필터링/소팅된 필드가 Couchbase에서 인덱싱되는지 확인하세요.
마무리
이러한 모든 통합은 EF Core에 의해 지원되며, 이제 Couchbase 지원을 통해 코드에서 이를 최대한 활용할 수 있습니다. 안전한 웹 애플리케이션을 구축하든, GraphQL API를 구축하든, BI 도구와 통합하든, EF Core와 Couchbase의 조합을 통해 모든 것이 가능합니다.
더 자세히 알고 싶으신가요? 다음에 어떤 통합 기능을 살펴보고 싶은지 알려주세요!