카우치베이스 서버 2.0 작업의 중요한 이점 중 하나는 유연한 스키마입니다. 문서는 JSON으로 저장되므로 서로 순서를 강요하지 않는 암시적 구조의 레코드가 가능합니다. 실제 세계에서 이러한 '암시적 구조'는 애플리케이션에서 비롯됩니다. 애플리케이션에서 새 사용자를 만들면 연결된 문서는 도메인 개체의 JSON 직렬화된 버전입니다.
{
[JsonIgnore]
public 문자열 Id { get; set; }
[제이슨 프로퍼티("username")]
public 문자열 사용자 이름 { get; set; }
[제이슨 프로퍼티("비밀번호")]
public 문자열 비밀번호 { get; set; }
[제이슨 프로퍼티("type")]
public 문자열 유형 { get { 반환 "user"; } }
}
//저장됨 { "사용자 이름" : "hmoody", "비밀번호" : "b3cca" }로 저장됩니다.
이 접근 방식은 잘 정의된 도메인 객체에서 문서를 읽고 쓰는 애플리케이션에서 일반적이지만, 문서 구조가 의도적으로 잘 정의되지 않은 경우도 있습니다. 이러한 경우에는 문서 유형별로 도메인 객체를 사용하는 것이 적합하지 않을 수 있습니다.
파이썬이나 루비 같은 언어에서는 덜 객체 지향적인 접근 방식(예: 사전이나 해시)을 사용하는 것이 일반적일 수 있지만, C#나 Java 같은 강력한 타입의 언어에서는 강력한 타입의 데이터 객체, 흔히 플레인 올드(Java|C#) 객체를 사용하여 애플리케이션 데이터를 표현하는 것이 훨씬 더 일반적입니다. 하지만 이러한 언어에서도 동적 언어 접근 방식을 사용할 수 있습니다.
최근 사용자가 다음과 같은 질문을 했을 때 스택오버플로우에서 에서 JSON 문서를 Couchbase에서 느슨하게 입력된 C# 객체로 가져오는 방법에 대해 설명하면서 두 가지 옵션을 제안했습니다. 이 글의 나머지 부분에서는 데이터에 비슷한 접근 방식을 취하는 데 사용할 수 있는 몇 가지 기본적인 확장 방법에 대해 설명하겠습니다.
첫 번째 접근 방식은 사전
이 문서를 저장하고 읽기 위해 사전을 저장하고 검색하는 확장 메서드를 추가하겠습니다. 이러한 메서드는 새로운 정적 클래스인 카우치베이스 동적 확장.
첫 번째 방법은 단순히 표준 ExecuteStore 메서드와 비슷하지만 몇 가지를 캡슐화합니다. 먼저, Newtonsoft.JSON 라이브러리를 사용하여 사전을 JSON으로 직렬화하는 작업을 처리합니다. 직렬화기 설정을 수정하여 낙타 대소문자 또는 기타 JSON 형식화 옵션을 지원할 수 있습니다. 기본값은 그대로 두었습니다. 두 번째로, 제가 캡슐화한 IStoreOperationResponse 의 세부 정보를 더 간단한 튜플 반환으로 변경했습니다. 튜플은 일반적으로 동적 언어에서 반환되며, 저는 좀 더 동적으로 만들려고 노력하고 있기 때문에 이것이 적절한 접근 방식인 것 같았습니다.
문자열 키, 사전<문자열, 객체> 사전)
{
var json = JsonConvert.SerializeObject(사전);
var 결과 = 클라이언트.ExecuteStore(storeMode, key, json);
만약 (!결과.성공)
{
만약 (결과.예외 != null) throw 결과.예외;
반환 튜플.만들기(false결과.상태 코드.HasValue ? 결과.상태 코드.가치 : -1결과.메시지);
}
반환 튜플.만들기(true, 0, 문자열.비어 있음);
}
저장된 JSON에서 사전을 다시 가져오는 것은 단순히 프로세스를 역전시키는 것입니다. 다시 말하지만, IGetOperationResult를 Tuple로 래핑하고 저장된 JSON을 사전
{
var 결과 = 클라이언트.ExecuteGet<문자열>(키);
만약 (!결과.성공)
{
만약 (결과.예외 != null) throw 결과.예외;
반환 튜플.만들기<bool, int, 문자열, 사전<문자열, 객체>>
(false결과.상태 코드.HasValue ? 결과.상태 코드.가치 : -1결과.메시지, null);
}
var dict = JsonConvert.역직렬화 개체<사전<문자열, 객체>>(결과.가치);
반환 튜플.만들기(true, 0, 문자열.비어 있음, 딕트);
}
저장 및 검색은 간단합니다(확장 클래스 네임스페이스에 사용자를 추가해야 합니다).
만약 (결과.Item1)
{
var dict = 클라이언트.GetDictionary("user_1").Item4;
콘솔.WriteLine(dict); //Dictionary.ToString()의 출력이어야 합니다.
}
더 흥미로운 접근 방식은 C#의 새로운 동적 입력 및 ExpandoObject 클래스. 이러한 기능을 통해 개발자는 컴파일 시점이 아닌 런타임에 컴파일러가 형식 검사를 수행하도록 지시할 수 있습니다. JSON 문서 작업은 다이내믹스의 훌륭한 사용 사례입니다.
동적 확장 메서드는 이전에는 사전이 있었다면 이제는 동적 유형이 있다는 점을 제외하면 거의 동일합니다.
문자열 키, ExpandoObject 객체)
{
var json = JsonConvert.SerializeObject(객체);
var 결과 = 클라이언트.ExecuteStore(storeMode, key, json);
만약 (!결과.성공)
{
만약 (결과.예외 != null) throw 결과.예외 as 예외;
반환 튜플.만들기(false결과.상태 코드.HasValue ? 결과.상태 코드.가치 : -1결과.메시지);
}
반환 튜플.만들기(true, 0, 문자열.비어 있음);
}
public 정적 튜플<bool, int, 문자열, ExpandoObject> GetDynamic(이 ICouchbaseClient 클라이언트, 문자열 키)
{
var 결과 = 클라이언트.ExecuteGet<문자열>(키);
만약 (!결과.성공)
{
만약 (결과.예외 != null) throw 결과.예외;
반환 튜플.만들기<bool, int, 문자열, ExpandoObject>
(false결과.상태 코드.HasValue ? 결과.상태 코드.가치 : -1결과.메시지, null);
}
var 객체 = JsonConvert.역직렬화 개체<ExpandoObject>(결과.가치);
반환 튜플.만들기(true, 0, 문자열.비어 있음, 객체);
}
그런 다음 코드에서 동적 인스턴스를 사용하여 Couchbase Server에 데이터를 저장하고 검색할 수 있습니다. 아래 코드 접근 방식을 사용하여 JSON 문서를 ExpandoObject로 읽을 수도 있습니다. 이를 테스트하려면 GetDynamic 키를 "user_1"로 설정합니다.
user2.사용자 이름 = "jzablocki";
user2.기본 설정 = new ExpandoObject();
user2.기본 설정.테마 = "green";
user2.기본 설정.시간대 = "EST";
클라이언트.StoreDynamic(스토어모드.설정, "user_2", user2 as ExpandoObject);
var getResult = 클라이언트.GetDynamic("user_2");
만약 (getResult.Item1)
{
동적 항목 = getResult.Item4;
콘솔.WriteLine(항목.기본 설정.테마);
}
동적 인수를 사용하여 확장 메서드를 호출할 때의 한계로 인해 캐스팅이 필요한 동적 확장에 대한 다른 접근 방식이 있습니다. 간단하게 설명하기 위해 저는 ExpandoObject 인수를 사용합니다.
공유해 주셔서 감사합니다...............
존 매우 유용한 게시물입니다.