사용자 도구

사이트 도구


product:povice:framework:collection

차이

문서의 선택한 두 판 사이의 차이를 보여줍니다.

차이 보기로 링크

양쪽 이전 판이전 판
product:povice:framework:collection [2022-11-15 15:20] – 제거됨 - 바깥 편집 (Unknown date) 127.0.0.1product:povice:framework:collection [2022-11-15 15:20] (현재) – ↷ 문서가 product:povice:collection에서 product:povice:framework:collection(으)로 이동되었습니다 shincs
줄 1: 줄 1:
 +====== 컬렉션 ======
 +
 +Data Collection에서 사용 가능한 컬렉션의 종류를 설명합니다.
 +
 +===== 용어의 정의 =====
 +
 +여기서는 필드와 속성을 모두 합쳐서 멤버(Member)라 정의합니다. 함수를 메서드라 부르고 List, Dictionary와 같은 데이터 형식을 컬렉션으로 부르기도 합니다.
 +
 +===== 계층 구조 =====
 +
 +최상위 계층인 ''TypeMapper'' 클래스를 상속받아 ''NotifyList<T>'' 컬렉션을 구현하였고 이 컬렉션을 기반으로 ''DataList<T>'' 와 ''VirtualList<T>'' 컬렉션을 구현하였습니다. 이러한 관계의 Class Diagram은 다음과 같습니다.
 +
 +{{:product:povice:632db341f528d770bdf766c713fc971f.png}}
 +
 +<wrap fontsize_12>[그림 1] DataList와 VirtualList의 Class Diagram</wrap>
 +
 +===== NotifyList<T> =====
 +
 +NotifyList는 컬렉션에서 항목이 추가되거나 제거가 되었을 때 혹은, 항목의 값이 변경되었을 때 알림을 받을 수 있는 컬렉션입니다.
 +
 +==== 멤버(Member) ====
 +
 +  * **this[int] : T**
 +      * 지정한 인덱스에 있는 요소를 가져오거나 설정합니다.
 +  * **Count : int**
 +      * NotifyList<T>에 실제로 포함된 요소의 수를 가져옵니다.
 +  * **InitInProgress : bool**
 +      * ISupportInitialize 인터페이스에 의해 BeginInit() 메서드가 호출되었는지 여부를 가져옵니다.
 +  * **ItemType : Type**
 +      * 항목의 형식을 가져옵니다.
 +  * **Members : MemberCollection**
 +      * 정의한 형식 멤버들에 대한 컬렉션을 가져옵니다.
 +  * **ReadOnly : bool**
 +      * NotifyList<T>가 읽기 전용인지 여부를 나타내는 값을 가져오거나 설정합니다. 기본값은 false입니다.
 +
 +==== 메서드(Method) ====
 +
 +  * **Add(T) : void**
 +      * 개체를 NotifyList<T>의 끝 부분에 추가합니다.
 +  * **AddRange(IEnumerable<T>) : void**
 +      * 지정된 컬렉션의 항목을 NotifyList<T>의 끝에 추가합니다.
 +  * **ApplyRange(IEnumerable<T>) : void**
 +      * 다시 적용하기위해 기존 항목들을 지우고 지정된 컬렉션의 항목을 NotifyList<T>에 추가합니다.
 +  * **BeginInit() : void**
 +      * 초기화가 시작됨을 개체에 알립니다.
 +  * **Clear() : void**
 +      * NotifyList<T>에서 요소를 모두 제거합니다.
 +  * **Contains(T) : bool**
 +      * NotifyList<T>에 요소가 있는지 여부를 확인합니다.
 +  * **CreateItem(params object[]) : object**
 +      * ItemType 속성값에 해당하는 형식을 생성합니다.
 +  * **CopyTo(T[], int) : void**
 +      * 현재 1차원 배열의 모든 요소를 지정된 1차원 배열에 복사합니다.
 +  * **EndInit() : void**
 +      * 초기화가 완료됨을 개체에 알립니다.
 +  * **GenerateCode() : string**
 +      * 형식 정보를 사용하여 클래스 구현 코드를 생성합니다.
 +  * **GetRange(int, int) : IList<T>**
 +      * 소스 NotifyList<T>에 있는 일련의 항목에 대한 단순 복사본을 만듭니다.
 +  * **IndexOf(T) : int**
 +      * NotifyList<T>에서 특정 항목의 인덱스를 결정합니다.
 +  * **Insert(int, T) : void**
 +      * 항목을 NotifyList<T>의 지정된 인덱스에 삽입합니다.
 +  * **Remove(T) : bool**
 +      * NotifyList<T>에서 맨 처음 발견되는 특정 개체를 제거합니다.
 +  * **RemoveAt(int) : void**
 +      * NotifyList<T>에서 지정한 인덱스의 항목을 제거합니다.
 +  * **RemoveRange(int, int) : void**
 +      * NotifyList<T>에서 항목의 범위를 제거합니다.
 +
 +==== 이벤트(Event) ====
 +
 +  * **AsyncCollectionChanged : NotifyCollectionChangedEventHandler**
 +      * 비동기로 컬렉션이 변경될 때 발생합니다.
 +  * **CollectionChanged : NotifyCollectionChangedEventHandler**
 +      * 컬렉션이 변경될 때 발생합니다.
 +  * **ValueChanged : EventHandler<object, ValueChangedEventArgs>**
 +      * 멤버의 값이 변경되면 발생합니다.
 +
 +=== 이벤트 발생 조건 ===
 +
 +기본적으로는 ''CollectionChanged''  이벤트와 ''ValueChanged''  이벤트가 발생합니다. 그리고, 값이 변경될 때 알림을 받을 수 있는 조건은 몇가지가 존재하며 그 조건이 만족되면 ValueChanged 이벤트가 발생합니다. 아래는 해당조건입니다.
 +
 +  * NotifyList<dynamic> 사용
 +  * NotifyList.Members[i].SetValue() 메서드를 사용 할 것
 +  * 클래스 선언 시 INotifyValueChanged 인터페이스를 상속 받아 구현 할 것
 +
 +**NotifyList<dynamic>**
 +
 +NotifyList<dynamic> 컬렉션은 Member를 직접 추가하거나 삭제할 수 있습니다. Member에 해당하는 값을 수정하면 ValueChanged 이벤트가 발생합니다. GenerateCode() 메서드를 호출하면 NotifyList<dynamic> 컬렉션에서 생성된 Member 정보를 사용하여 아래와 유사한 클래스 구조의 코드를 생성합니다.
 +
 +<code csharp>
 +#region ClassName
 +/// <summary>
 +/// 클래스를 정의합니다.
 +/// </summary>
 +public class ClassName
 +{
 +    /// <summary>RegionID 입니다.</summary>
 +    public long RegionID;
 +    /// <summary>RegionDescription 입니다.</summary>
 +    public string RegionDescription;
 +}
 +#endregion
 +
 +
 +</code>
 +
 +**NotifyList.Members[i].SetValue() 메서드**
 +
 +T 타입에 상관없이 SetValue() 메서드를 사용하면 ValueChanged 이벤트가 항상 발생합니다.
 +
 +**INotifyValueChanged 인터페이스 상속**
 +
 +클래스를 선언할 때 INotifyValueChanged 인터페이스를 상속받고 속성 값이 변경될 때 ValueChanged 이벤트를 호출해주는 패턴을 구현합니다. 아래는 구현 방법입니다.
 +
 +<code csharp>
 +/// <summary>
 +/// INotifyValueChanged 인터페이스를 사용하는 예제입니다.
 +/// </summary>
 +public class TestClass : INotifyValueChanged
 +{
 +    /// <summary>
 +    /// 멤버의 값이 변경될 때 발생합니다.
 +    /// </summary>
 +    public event EventHandler<ValueChangedEventArgs> ValueChanged;
 +    /// <summary>
 +    /// ID 값입니다.
 +    /// </summary>
 +    string id;
 +    /// <summary>
 +    /// ID 값을 가져오거나 설정합니다.
 +    /// </summary>
 +    public string Id
 +    {
 +        get => this.id;
 +        set
 +        {
 +            var oldValue = this.id;
 +            this.id = value;
 +            // 변경 후 이벤트를 호출합니다.
 +            this.ValueChanged?.Invoke(this, new ValueChangedEventArgs(this,
 +            nameof(Id), value, oldValue));
 +        }
 +    }
 +}
 +
 +
 +</code>
 +
 +==== LINQ 지원 ====
 +
 +다음과 같이 LINQ 구문이 사용 가능합니다.
 +
 +<code csharp>
 +var enumerable = from item in notifyList
 +                 where item.Category == "Category1"
 +                 select item;
 +
 +
 +</code>
 +
 +===== DataList<T> =====
 +
 +''NotifyList<T>''  컬렉션을 상속받아 구현되었고 UI 컨트롤에 바인딩이 가능하도록 설계되었습니다. NotifyList<T> 컬렉션에서 데이터를 필터링하는 기능과 정렬하는 기능이 포함되었습니다.
 +
 +==== 멤버(Member) ====
 +
 +  * **this[int] : T**
 +      * 지정한 인덱스에 있는 요소를 가져오거나 설정합니다.
 +  * **Count : int**
 +      * DataList<T>에 실제로 포함된 요소의 수를 가져옵니다.
 +  * **Filters : FilterCollection**
 +      * 필터의 컬렉션을 가져옵니다. 설정되지 않았을 경우 Count가 0입니다.
 +  * **InitInProgress : bool**
 +      * ISupportInitialize 인터페이스에 의해 BeginInit() 메서드가 호출되었는지 여부를 가져옵니다.
 +  * **ItemType : Type**
 +      * 항목의 형식을 가져옵니다.
 +  * **Members : MemberCollection**
 +      * 정의한 형식 멤버들에 대한 컬렉션을 가져옵니다.
 +  * **ReadOnly : bool**
 +      * DataList<T>가 읽기 전용인지 여부를 나타내는 값을 가져오거나 설정합니다. 기본값은 false입니다.
 +  * **Sorts : SortCollection**
 +      * 정렬의 컬렉션을 가져옵니다. 설정되지 않았을 경우 Count가 0입니다.
 +
 +==== 메서드(Method) ====
 +
 +  * **Add(T) : void**
 +      * 개체를 DataList<T>의 끝 부분에 추가합니다.
 +  * **AddRange(IEnumerable<T>) : void**
 +      * 지정된 컬렉션의 항목을 DataList<T>의 끝에 추가합니다.
 +  * **ApplyRange(IEnumerable<T>) : void**
 +      * 다시 적용하기위해 기존 항목들을 지우고 지정된 컬렉션의 항목을 DataList<T>에 추가합니다.
 +  * **BeginInit() : void**
 +      * 초기화가 시작됨을 개체에 알립니다.
 +  * **Clear() : void**
 +      * DataList<T>에서 요소를 모두 제거합니다.
 +  * **Contains(T) : bool**
 +      * DataList<T>에 요소가 있는지 여부를 확인합니다.
 +  * **CreateItem(params object[]) : object**
 +      * ItemType 속성값에 해당하는 형식을 생성합니다.
 +  * **CopyTo(T[], int) : void**
 +      * 현재 1차원 배열의 모든 요소를 지정된 1차원 배열에 복사합니다.
 +  * **EndInit() : void**
 +      * 초기화가 완료됨을 개체에 알립니다.
 +  * **Find(string, object) : int**
 +      * 컬렉션에서 멤버 이름과 값이 일치하는 항목의 인덱스를 반환합니다.
 +  * **GenerateCode() : string**
 +      * 형식 정보를 사용하여 클래스 구현 코드를 생성합니다.
 +  * **GetRange(int, int) : IList<T>**
 +      * 소스 DataList<T>에 있는 일련의 항목에 대한 단순 복사본을 만듭니다.
 +  * **IndexOf(T) : int**
 +      * DataList<T>에서 특정 항목의 인덱스를 결정합니다.
 +  * **Insert(int, T) : void**
 +      * 항목을 DataList<T>의 지정된 인덱스에 삽입합니다.
 +  * **Remove(T) : bool**
 +      * DataList<T>에서 맨 처음 발견되는 특정 개체를 제거합니다.
 +  * **RemoveAt(int) : void**
 +      * DataList<T>에서 지정한 인덱스의 항목을 제거합니다.
 +  * **RemoveRange(int, int) : void**
 +      * DataList<T>에서 항목의 범위를 제거합니다.
 +  * **SetValue(object, string, object) : void**
 +      * 항목의 값을 변경합니다. 변경된 후에 ValueChanged 이벤트가 발생합니다.
 +
 +==== 이벤트(Event) ====
 +
 +  * **AsyncCollectionChanged : NotifyCollectionChangedEventHandler**
 +      * 비동기로 컬렉션이 변경될 때 발생합니다.
 +  * **CollectionChanged : NotifyCollectionChangedEventHandler**
 +      * 컬렉션이 변경될 때 발생합니다.
 +  * **ValueChanged : EventHandler<object, ValueChangedEventArgs>**
 +      * 멤버의 값이 변경되면 발생합니다.
 +
 +==== 필터(Filter) ====
 +
 +필터 기능을 위해 ''Filters''  컬렉션 속성을 사용하며, 사용 방법은 아래와 같습니다. Add() 메서드를 사용하여 필터를 여러 번 추가하면, 필터 적용이 여러 번 수행되어 성능이 저하될 수 있습니다. 이럴 경우, AddRange() 메서드를 사용하여 2개 이상의 필터 조건을 한 번에 적용하는 것을 고려해야 합니다.
 +
 +<code csharp>
 +dataList.Filters.Add("rowid", RelationalOperator.LessThanOrEqual, 1000);
 +
 +
 +</code>
 +
 +==== 정렬(Sort) ====
 +
 +정렬 기능을 위해 ''Sorts''  컬렉션 속성을 사용하며, 사용 방법은 아래와 같습니다. 필터와 동일하게 Add() 메서드를 사용하여 정렬을 여러 번 추가하면, 정렬 적용이 여러번 수행되어 성능이 저하될 수 있습니다. 이럴 경우, AddRange() 메서드를 사용하여 2개 이상의 정렬 조건을 한 번에 적용하는 것을 고려해야 합니다.
 +
 +<code csharp>
 +dataList.Sorts.Add("rowid", ListSortDirection.Descending);
 +
 +
 +</code>
 +
 +===== VirtualList<T> =====
 +
 +데이터베이스의 테이블의 항목이 추가 또는 제거되거나 전체 목록이 새로 고쳐질 때 알림을 제공하는 동적 데이터 컬렉션을 나타냅니다. VirtualList<T>는 다음과 같은 특징을 가지고 있습니다.
 +
 +  * 대용량 처리를 위해 데이터는 RDB에 적재하고 사용할 때는 필요한 부분만 가져옵니다.
 +  * In-memory, Caching, Dynamic Query 최적화를 통해 기본 성능을 향상시킵니다.
 +  * 전체 데이터를 검색할 경우 성능을 위해 foreach를 사용하여야 합니다.
 +
 +**선언 방법**
 +
 +기본적인 선언 방법은 다음과 같습니다.
 +
 +<code csharp>
 +var virtualList = new VirtualList<dynamic>("TableName", "SQLite");
 +
 +</code>
 +
 +==== 멤버(Member) ====
 +
 +  * **this[int] : T**
 +      * 지정한 인덱스에 있는 요소를 가져오거나 설정합니다.
 +  * **ConnectionName : string**
 +      * 연결 이름을 가져옵니다.
 +  * **Count : int**
 +      * VirtualList<T>에 실제로 포함된 요소의 수를 가져옵니다.
 +  * **Filters : FilterCollection**
 +      * 필터의 컬렉션을 가져옵니다. 설정되지 않았을 경우 Count가 0입니다.
 +  * **InitInProgress : bool**
 +      * ISupportInitialize 인터페이스에 의해 BeginInit() 메서드가 호출되었는지 여부를 가져옵니다.
 +  * **ItemIdColumnName : string**
 +      * 항목 ID 값을 가지는 컬럼 이름을 가져오거나 설정합니다.
 +  * **ItemType : Type**
 +      * 항목의 형식을 가져옵니다.
 +  * **Members : MemberCollection**
 +      * 정의한 형식 멤버들에 대한 컬렉션을 가져옵니다.
 +  * **ReadOnly : bool**
 +      * VirtualList<T>가 읽기 전용인지 여부를 나타내는 값을 가져오거나 설정합니다. 기본값은 false입니다.
 +  * **Sorts : SortCollection**
 +      * 정렬의 컬렉션을 가져옵니다. 설정되지 않았을 경우 Count가 0입니다.
 +  * **TableName : string**
 +      * 테이블 이름을 가져옵니다.
 +
 +==== 메서드(Method) ====
 +
 +  * **Add(T) : void**
 +      * 개체를 VirtualList<T>의 끝 부분에 추가합니다.
 +  * **AddRange(IEnumerable<T>) : void**
 +      * 지정된 컬렉션의 항목을 VirtualList<T>의 끝에 추가합니다.
 +  * **ApplyRange(IEnumerable<T>) : void**
 +      * 다시 적용하기위해 기존 항목들을 지우고 지정된 컬렉션의 항목을 VirtualList<T>에 추가합니다.
 +  * **BeginInit() : void**
 +      * 초기화가 시작됨을 개체에 알립니다.
 +  * **Clear() : void**
 +      * DataList<T>에서 요소를 모두 제거합니다.
 +  * **Contains(T) : bool**
 +      * DataList<T>에 요소가 있는지 여부를 확인합니다.
 +  * **CreateItem(params object[]) : object**
 +      * ItemType 속성값에 해당하는 형식을 생성합니다.
 +  * **CopyTo(T[], int) : void**
 +      * 현재 1차원 배열의 모든 요소를 지정된 1차원 배열에 복사합니다.
 +  * **EndInit() : void**
 +      * 초기화가 완료됨을 개체에 알립니다.
 +  * **Find(string, object) : int**
 +      * 컬렉션에서 멤버 이름과 값이 일치하는 항목의 인덱스를 반환합니다.
 +  * **GenerateCode() : string**
 +      * 형식 정보를 사용하여 클래스 구현 코드를 생성합니다.
 +  * **GetRange(int, int) : IList<T>**
 +      * 소스 VirtualList<T>에 있는 일련의 항목에 대한 단순 복사본을 만듭니다.
 +  * **IndexOf(T) : int**
 +      * VirtualList<T>에서 특정 항목의 인덱스를 결정합니다.
 +  * **Remove(T) : bool**
 +      * VirtualList<T>에서 맨 처음 발견되는 특정 개체를 제거합니다.
 +  * **RemoveAt(int) : void**
 +      * VirtualList<T>에서 지정한 인덱스의 항목을 제거합니다.
 +  * **RemoveRange(int, int) : void**
 +      * VirtualList<T>에서 항목의 범위를 제거합니다.
 +  * **SetValue(object, string, object) : void**
 +      * 항목의 값을 변경합니다. 변경된 후에 ValueChanged 이벤트가 발생합니다.
 +
 +==== 이벤트(Event) ====
 +
 +  * **AsyncCollectionChanged : NotifyCollectionChangedEventHandler**
 +      * 비동기로 컬렉션이 변경될 때 발생합니다.
 +  * **CollectionChanged : NotifyCollectionChangedEventHandler**
 +      * 컬렉션이 변경될 때 발생합니다.
 +  * **ValueChanged : EventHandler<object, ValueChangedEventArgs>**
 +      * 멤버의 값이 변경되면 발생합니다.
 +
 +==== 필터(Filter) ====
 +
 +필터 기능을 위해 ''Filters''  컬렉션 속성을 사용하며, 사용 방법은 아래와 같습니다. DataList<T> 컬렉션과 다르게 Add() 메서드를 사용하여 필터 조건을** 여러 번 추가하여도 성능에 영향을 받지 않습니다**. VirtualList<T> 컬렉션은 필터 적용 후 실제 사용 시점에 데이터를 쿼리하기 떄문입니다.
 +
 +<code csharp>
 +virtualList.Filters.Add("rowid", RelationalOperator.LessThanOrEqual, 1000);
 +// 필터 적용 후 아래와 같이 실제 사용 시점에 쿼리 후 데이터를 가져옵니다.
 +var item = virtualList[2];
 +
 +</code>
 +
 +==== 정렬(Sort) ====
 +
 +정렬 기능을 위해 ''Sorts''  컬렉션 속성을 사용하며, 사용 방법은 아래와 같습니다. DataList<T> 컬렉션과 다르게 Add() 메서드를 사용하여 정렬 조건을 **여러 번 추가하여도 성능에 영향을 받지 않습니다**. VirtualList<T> 컬렉션은 정렬 적용 후 실제 사용 시점에 데이터를 쿼리하기 떄문입니다.
 +
 +<code csharp>
 +virtualList.Sorts.Add("rowid", ListSortDirection.Descending);
 +// 정렬 적용 후 아래와 같이 실제 사용 시점에 쿼리 후 데이터를 가져옵니다.
 +var item = virtualList[2];
 +
 +</code>
 +