LINQ to SQL은 그리드 컨트롤과 같은 공통 컨트롤에 대한 바인딩을 지원합니다. 특히 LINQ to SQL은 표시 및 업데이트와 관련하여 데이터 그리드에 바인딩하고 마스터-세부 바인딩을 처리하는 기본 패턴을 정의합니다.
기본 원칙
LINQ to SQL은 데이터베이스에서 실행하기 위해 LINQ 쿼리를 SQL로 변환합니다. 결과는 엄격하게 형식화되었습니다 IEnumerable. 이러한 개체는 일반적인 CLR(공용 언어 런타임) 개체이므로 일반 개체 데이터 바인딩을 사용하여 결과를 표시할 수 있습니다. 반면에 변경 작업(삽입, 업데이트 및 삭제)에는 추가 단계가 필요합니다.
수술
Windows Forms 컨트롤에 암시적으로 바인딩하는 것은 IListSource를 구현하여 수행됩니다. 데이터 소스 제네릭 Table<TEntity> (Table<T> C# 또는 Table(Of T) Visual Basic)과 제네릭 DataQuery이 IListSource을 구현하도록 업데이트되었습니다. UI(사용자 인터페이스) 데이터 바인딩 엔진(Windows Forms 및 Windows Presentation Foundation)은 둘 다 데이터 원본이 구현하는지 여부를 테스트합니다 IListSource. 따라서 쿼리의 직접적인 영향을 컨트롤의 데이터 원본에 기록하는 경우, 아래의 예와 같이 LINQ to SQL을 이용한 컬렉션 생성이 암시적으로 호출됩니다.
DataGrid dataGrid1 = new DataGrid();
DataGrid dataGrid2 = new DataGrid();
DataGrid dataGrid3 = new DataGrid();
var custQuery =
from cust in db.Customers
select cust;
dataGrid1.DataSource = custQuery;
dataGrid2.DataSource = custQuery;
dataGrid2.DataMember = "Orders";
BindingSource bs = new BindingSource();
bs.DataSource = custQuery;
dataGrid3.DataSource = bs;
Dim dataGrid1 As New DataGrid()
Dim dataGrid2 As New DataGrid()
Dim dataGrid3 As New DataGrid()
Dim custQuery = _
From cust In db.Customers _
Select cust
dataGrid1.DataSource = custQuery
dataGrid2.DataSource = custQuery
dataGrid2.DataMember = "Orders"
Dim bs = _
New BindingSource()
bs.DataSource = custQuery
dataGrid3.DataSource = bs
Windows Presentation Foundation도 마찬가지입니다.
ListView listView1 = new ListView();
var custQuery2 =
from cust in db.Customers
select cust;
ListViewItem ItemsSource = new ListViewItem();
ItemsSource = (ListViewItem)custQuery2;
Dim listView1 As New ListView()
Dim custQuery2 = _
From cust In db.Customers _
Select cust
Dim ItemsSource As New ListViewItem
ItemsSource = custQuery2
컬렉션 세대는 제네릭 Table<TEntity> 및 제네릭 DataQuery 에서 구현됩니다 GetList.
IListSource 구현
LINQ to SQL은 다음 두 위치에서 구현합니다 IListSource .
데이터 원본은 다음과 같습니다 Table<TEntity>. LINQ to SQL은 테이블에 대한 참조를
DataBindingList유지하는 컬렉션을 채우기 위해 테이블을 찾습니다.데이터 원본은 IQueryable<T>입니다. 두 가지 시나리오가 있습니다.
LINQ to SQL이 Table<TEntity>부터 기본 IQueryable<T>을 찾으면 원본에서 편집이 가능하며 상황은 처음 항목과 동일합니다.
LINQ to SQL에서 기본 Table<TEntity>버전을 찾을 수 없는 경우 원본은 버전(예:
groupby)을 허용하지 않습니다. LINQ to SQL은 지정된 속성에 대한 T 엔터티의 정렬 기능을 구현하는 간단한SortableBindingList제네릭BindingList<T>을 채우기 위해 쿼리를 검색합니다.
특수 컬렉션
이 문서의 BindingList<T> 앞부분에서 설명한 많은 기능의 경우 몇 가지 다른 클래스에 특수화되어 있습니다. 이러한 클래스는 제네릭 SortableBindingList 및 제네릭 DataBindingList입니다. 둘 다 내부로 지정됩니다.
Generic SortableBindingList (범용 정렬 가능 바인딩 목록)
이 클래스는 BindingList<T>로부터 상속받으며, BindingList<T>의 정렬 가능한 버전입니다. 정렬은 메모리 내 솔루션이며 데이터베이스 자체에 연결되지 않습니다.
BindingList<T>는 IBindingList을(를) 구현하지만, 기본적으로 정렬은 지원하지 않습니다. 그러나 BindingList<T> 가상 IBindingList 메서드를 사용하여 구현합니다. 이러한 메서드를 쉽게 재정의할 수 있습니다. 제네릭 SortableBindingList 대체 SupportsSortingCore, SortPropertyCore, SortDirectionCore 및 ApplySortCore를.
ApplySortCore는 ApplySort에 의해 호출되며, 지정된 속성에 대한 T 항목 목록을 정렬합니다.
속성이 T에 속하지 않으면 예외가 발생합니다.
정렬을 수행하기 위해 LINQ to SQL은 제네릭 SortableBindingList.PropertyComparer 클래스를 생성하여 제네릭 IComparer.Compare으로부터 상속받고, 지정된 형식 T와 PropertyDescriptor, 및 방향에 대한 기본 비교자를 구현합니다. 이 클래스는 Comparer의 PropertyType인 T의 PropertyDescriptor을 동적으로 생성합니다. 그런 다음 기본 비교자는 정적 제네릭 Comparer에서 검색됩니다. 리플렉션을 사용하여 기본 인스턴스를 가져옵니다.
제네릭 SortableBindingList 은 .의 기본 클래스이기도 합니다 DataBindingList. 제네릭 SortableBindingList 은 항목 추가/제거 추적을 일시 중단하거나 다시 열기 위한 두 가지 가상 메서드를 제공합니다. 이러한 두 메서드는 정렬과 같은 기본 기능에 사용할 수 있지만 제네릭 DataBindingList과 같은 상류 클래스에서 실제로 구현됩니다.
제네릭 데이터 바인딩 리스트 (Generic DataBindingList)
이 클래스는 제네릭 SortableBindingLIst에서 상속됩니다. 제네릭 DataBindingList은 컬렉션의 초기 채우기에 사용된 제네릭 Table의 기본 제네릭 IQueryable에 대한 참조를 유지합니다. 제네릭 DatabindingList은 InsertItem() 및 RemoveItem()를 재정의하여 컬렉션에 항목 추가/제거를 추적합니다. 또한 추상 일시 중단/다시 시작 추적 기능을 구현하여 추적을 조건부로 만듭니다. 이 기능을 사용하면 제네릭 DataBindingList 이 부모 클래스의 추적 기능의 모든 다형적 사용을 활용할 수 있습니다.
EntitySets에 바인딩
EntitySet에 바인딩하는 것은 특별한 경우입니다. 왜냐하면 EntitySet는 이미 IBindingList을 구현하는 컬렉션이기 때문입니다. LINQ to SQL은 정렬 및 취소(ICancelAddNew) 지원을 추가합니다. 클래스는 EntitySet 내부 목록을 사용하여 엔터티를 저장합니다. 이 목록은 제네릭 배열인 ItemList 제네릭 클래스를 기반으로 하는 하위 수준 컬렉션입니다.
정렬 기능 추가
배열은 T의 Array.Sort()과 함께 사용할 수 있는 정렬 메서드(Comparer)를 제공합니다. LINQ to SQL은 이 주제의 앞부분에서 설명한 제네릭 SortableBindingList.PropertyComparer 클래스를 사용하여 정렬할 속성 및 방향에 대한 Comparer를 가져옵니다.
ApplySort 이 기능을 호출하기 위해 제네릭 ItemList 에 메서드가 추가됩니다.
EntitySet 측에서 이제 정렬 지원을 선언해야 합니다.
SupportsSorting은(는)
true을(를) 반환합니다.ApplySort,
entities.ApplySort()를 호출한 다음OnListChanged()를 호출합니다.SortDirection 및 SortProperty 속성은 로컬 멤버에 저장된 현재 정렬 정의를 노출합니다.
System.Windows.Forms.BindingSource를 사용하고 EntitySet<TEntity>를 System.Windows.Forms.BindingSource.DataSource에 바인딩하는 경우, BindingSource.List를 업데이트하기 위해 EntitySet<TEntity>.GetNewBindingList를 호출해야 합니다.
System.Windows.Forms.BindingSource를 사용하고 BindingSource.DataMember 속성을 설정하고 BindingSource.DataSource를 EntitySet TEntity<를 노출하는 BindingSource.DataMember에 이름이 지정된 속성이 있는 클래스로 설정하는 경우 EntitySet><TEntity>를 호출할 필요가 없습니다. GetNewBindingList를 사용하여 BindingSource.List를 업데이트하지만 정렬 기능이 손실됩니다.
캐싱 (데이터 임시 저장)
LINQ to SQL 쿼리는 GetList를 구현합니다. Windows Forms BindingSource 클래스가 이 인터페이스를 충족하는 경우 단일 연결에 대해 GetList()를 세 번 호출합니다. 이 상황을 해결하기 위해 LINQ to SQL은 인스턴스당 캐시를 구현하여 항상 동일한 생성된 컬렉션을 저장하고 반환합니다.
취소
IBindingList 는 컨트롤에서 AddNew 바인딩된 컬렉션에서 새 항목을 만드는 데 사용하는 메서드를 정의합니다. 컨트롤은 DataGridView 마지막으로 표시되는 행에 머리글에 별표가 포함된 경우 이 기능을 아주 잘 보여 줍니다. 별표는 새 항목을 추가할 수 있음을 보여줍니다.
이 기능 외에도 컬렉션에서 구현 ICancelAddNew할 수도 있습니다. 이 기능을 사용하면 컨트롤에서 편집된 새 항목의 유효성이 검사되었는지 여부를 취소하거나 유효성을 검사할 수 있습니다.
ICancelAddNew는 모든 LINQ to SQL 데이터 바인딩 컬렉션(제네릭 SortableBindingList 및 제네릭 EntitySet)에서 구현됩니다. 두 구현에서 코드는 다음과 같이 수행합니다.
항목을 삽입한 다음 컬렉션에서 제거할 수 있습니다.
UI가 버전을 커밋하지 않는 한 변경 내용을 추적하지 않습니다.
버전이 취소되는 한 변경 내용을 추적하지 않습니다(CancelNew).
버전이 커밋된 시점(EndNew)을 추적할 수 있습니다.
새 항목이 AddNew에서 비롯되지 않는 경우 컬렉션이 정상적으로 작동하도록 합니다.
문제 해결
이 섹션에서는 LINQ to SQL 데이터 바인딩 애플리케이션 문제를 해결하는 데 도움이 될 수 있는 몇 가지 항목을 설명합니다.
속성을 사용해야 합니다. 필드만 사용하는 것만으로는 충분하지 않습니다. Windows Forms를 사용하려면 이 사용법이 필요합니다.
기본적으로
image,varbinary및timestamp데이터베이스 형식은 바이트 배열에 매핑됩니다.ToString()이 시나리오에서는 지원되지 않으므로 이러한 개체를 표시할 수 없습니다.기본 키에 매핑된 클래스 멤버에는 setter가 있지만 LINQ to SQL은 개체 ID 변경을 지원하지 않습니다. 따라서 매핑에 사용되는 기본/고유 키는 데이터베이스에서 업데이트할 수 없습니다. 그리드를 변경하면 호출 SubmitChanges할 때 예외가 발생합니다.
엔터티가 두 개의 개별 그리드(예: 하나의 마스터 및 다른 세부 정보)에 바인딩된 경우 마스터 그리드의 한
Delete항목이 세부 정보 표로 전파되지 않습니다.