두 테이블 간의 외래 키 관계가있는 Linq to SQL EntitySet이 있습니다. 해당 테이블은 작업 테이블 (Issues라고 함)과 부서 테이블입니다. 외래 키는 부서명 (어느 것이 고유한지)입니다. 관련 데이터가로드 된 경우 Linq to SQL FK 필드를 변경할 수 없다는 문제가 있습니다.wpf 콤보 상자를 Linq to SQL 외래 키 속성에 바인딩하는 방법
뷰 모델은 (진실하지 MVVM, 내가 XAML, WPF 및 Linq는-SQL을 배우면서 개념을 실천하기 위해 노력하고 있어요)
public class StatusBoardViewModel : INotifyPropertyChanged
{
OIConsoleDataContext db = new OIConsoleDataContext();
private IQueryable<Issue> issues;
public IQueryable<Issue> Issues
{
get { // Lazy load issues if they have not been instantiated yet
if (issues == null) {
QueryIssues();
}
return issues;
}
set {
if (issues != value) {
issues = value;
OnPropertyChanged("Issues");
}
}
}
private IQueryable<Department> departments;
public IQueryable<Department> Departments
{
get {
// Lazy load departments if they have not been instantiated yet
if (departments == null) {
QueryDepartments();
}
return departments;
}
set {
if (departments != value) {
departments = value;
OnPropertyChanged("Departments");
}
}
}
private void QueryDepartments()
{
Departments = from d in db.Departments
orderby d.DeptName
select d;
}
public void QueryIssues()
{
Issues = from i in db.Issues
where i.IssIsOpen == true
orderby i.IssDueDate
select i;
// ....
}
#region INotifyPropertyChanged Members
}
내 콤보 상자 :
<ComboBox x:Name="DeptComboBox"
ItemsSource="{Binding Departments}"
DisplayMemberPath="DeptName"
SelectedValuePath="DeptName"
SelectedValue="{Binding Path=Issues/IssDepartment, Mode=TwoWay}"
Grid.Column="2" Grid.ColumnSpan="2" Grid.Row="3" Margin="6,7,115,5"
IsSynchronizedWithCurrentItem="True" />
는 그것을 의미로 콤보 상자를 잘 표시하고 선택 항목을 올바른 부서로 기본 설정하지만 변경하면 예외가 발생합니다. 'System.Data.Linq.ForeignKeyReferenceAlreadyHasValueException'
다음 다음 새 하나를 추가 부서 참조를 제거 뒤에 다음 코드를 사용하여 콤보 상자에
SelectionChanged="DeptComboBox_SelectionChanged"
를 추가했습니다. 잘 작동하는 것처럼 보였지만 필터 설정에 따라 linq 쿼리가 변경된 경우 Selection_Changed 이벤트가 발생하면 변경 전의 새 항목이 새 기본 항목 부서의 값으로 변경됩니다. 선택 변경 이벤트가 바인딩 속성이 아니라이를 방지하기 위해 사용자가 보낸 것인지 확인할 수있는 방법을 찾지 못했습니다. 게다가 코드 바인딩을 사용하거나 적어도 어떤 종류의 값 변환기에 있어야하는 코드 사용에 만족하지 않았습니다.
나 자신에게 정직해야// This was an attempt to work around that did not work
// The referneces are passed from the Window1 event handler
public void ChangeDepartment(Issue currentIssue, Department currentDept)
{
if (currentIssue != null) {
currentIssue.Department = null;
currentIssue.Department = currentDept;
}
}
,
나는이 어떻게
처리해야 .. 여기 내 급여 등급 이상에서 오전 있지만 가장 어 배울 때이다? 나는 그 문제에 관한 12 개의 기사를 읽고 그것들이 진흙처럼 모순되고 분명한 것으로 판명했다. 모든 도움을감사 SO
나는 아래 크리스 니콜과 매우 유용한 토론이 있고 나는 일에 더 나은 핸들이 있다면 그는 이미 확인 표시가 아마 것 마이크
업데이트 . 필자는 가장 큰 문제는 SQL, Linq, WPF 및 데이터베이스 디자인을 한꺼번에 배우는 것입니다. 나는 모든 주제에 대해 훌륭한 책을 가지고 있지만 상호 운용성에 대해서는 다루지 않습니다. 예를 들어 C# 2008의 Pro Linq는 훌륭합니다 ... WPQ의 Linq에 대해 전혀 이야기하지 않는 것을 제외하고는
가능한 한 "MVVMish"로 작업하려고했지만 이전에 몇 차례 잘못 시작한 후, 한 번에 배울 수있는 것이 너무 많다는 결론을 내 렸습니다. 실제로는 명령이 없다는 것을 제외하고는 MVVM에 가깝다고 생각합니다. 코드 뒤의 이벤트 핸들러에서 ViewModel 클래스의 메서드를 실행합니다. 나중에 지휘 체계에서 리팩토링하는 것이 상당히 쉽다고 가정하고 있습니다.
모델
- Linq에이 파일 DBML SQL로 DataErrorInfo 확인을위한
- 부분 클래스를
뷰 모델
- 를 다음과 같이 내 응용 프로그램이 구성되어 DataCon 다른 목록 상자를 트리거 텍스트 (ShowDetailListItems 같은 바인딩 할 보려면 추가/편집 창보기로
- 일부 속성을 사용하는 작업, 직원 및 부서
- 선택된 작업의 속성에 대한
- 된 IQueryable 컬렉션) ItemTemplate 자체이며 확인란 자체에 바인딩됩니다.
- querys를 수행하는 메소드
- 태스크를 추가하거나 편집하기위한 창을 열고 해당 창에서 복귀 할 때 submitChanges() 메소드.
보기는 뷰 모델에 바인딩하고 코드 뒤에이 포함되어 있습니다 :
- 생성자의 뷰 모델의 인스턴스를 뷰 모델 클래스
- 코드의 인스턴스를 보유 속성과 viewModel에 datacontext를 설정하는 방법
- 나머지 코드는 결과적으로 명령으로 대체되는 이벤트 처리기입니다.
나는 Josh Smiths 우수 기사를 여러 번 읽었으며 샘플 코드를 살펴 보았습니다. 내 형식의 대부분은 그것을 기반으로합니다. Chris (Below)가 목록을 작성한 스레드는 내가 탐구 할 톤이나 새로운 자료를 가지고 있으므로, 시간을 들여 파고 들어서 리팩터링하는 방법을 결정하려고합니다. 실제로 작동하지 않는 ComboBoxes를 훨씬 뛰어 넘었습니다. 실제로 원래 문제의 일부는 콤보 상자가 두 개의 다른 데이터 컨텍스트에 바인딩된다는 것입니다. 내가 관리할만한 아키텍처를 가질 때까지 나는 그 일을 패치하기 위해 노력하는 것이 더 해롭다 고 생각합니다.
아마
유감스럽게도 크리스
에 대한 확인 표시와 함께 나중에 다시 될 것입니다 : "시도가 부착하거나, 새로운 아마도 다른 DataContext에로드 된없는 엔티티를 추가하기위한 것으로 ..."
좋아요. 나는이 작업을했지만 해결 방법은 내가 싫어하는 엄청난 해킹입니다.내 게시물의 끝에서 이벤트를 사용하여 'UpdatingQuery'클래스에 속성을 추가 한 다음 쿼리를 변경하는 동안이 속성을 true로 설정했습니다. 그런 다음 ChangeDepartment에 검사를 추가하여 업데이트가 지연되는 변경 사항을 제외했습니다. OUCH 옳은 길을 찾아야합니다. 나쁜 습관을 배우는 것이 싫어요! –