2014-11-06 2 views
0

Visual Studio Express 2013 및 SQL Server Express 2014를 사용하여 LINQ to SQL을 사용하여 WPF 응용 프로그램에 데이터를 액세스합니다. 내 의도는 observableCollections에 매핑 된 다양한 UI 요소를 사용하여 완전한 CRUD 기능입니다. 지금까지 모든 것이 잘 작동하지만 나는 단지 DataGrid에 매핑 된 개별 테이블을 사용하고 있습니다. 두 테이블의 왼쪽 조인 결과를 하나의 DataGrid로 표시하려면 dbml 레이아웃에서 새 테이블을 만들고 데이터 소스로 저장 프로 시저를 사용하십시오. IDE 생성 코드는 다음과 같습니다.WPF LINQ to SQL 클래스 사용자 지정

[global::System.Data.Linq.Mapping.TableAttribute(Name="dbo.ListAllDocuments")] 
public partial class TrackDocument : INotifyPropertyChanging, INotifyPropertyChanged 
{ // innards removed for readability } 

실행하면 처리되지 않은 예외 "잘못된 개체 이름 'dbo.ListAllDocuments'가 발생합니다. . . 이것은 Left Join 문과 함께 저장 프로 시저입니다. 이 데이터를 나타 내기 위해 작성한 클래스에 쿼리 언어를 추가하려면 어떻게해야합니까? 여기에 내가 UI에 최종 바인딩에 대한 단일 테이블 케이스 모델링 생성자를 관찰 할 수있는 클래스입니다 :

class ObservableTrackDocument : ObservableCollection<TrackDocument> 
{ 
    public ObservableTrackDocument(DocControlClassesDataContext dataDc) 
    { 
     foreach (TrackDocument tDoc in dataDc.TrackDocuments) 
     { 
      this.Add(tDoc); 
     } 
    } 
} 

는 그러나 저장 프로 시저를 소스로 사용 할 수 없기 때문에 데이터 컨텍스트는 테이블 작성되지 않았습니다. 중 (필자는 "소스를 remvove

class ObservableTrackDocument : ObservableCollection<TrackDocument> 
{ 
    public ObservableTrackDocument(DocControlClassesDataContext dataDc) 
    { 
     var query = from f in dataDc.FilesTransmitteds 
        from r in dataDc.FilesReturneds 
        .Where(x => f.DocumentNumber == x.DocumentNumber && f.REV == x.REV) 
        .DefaultIfEmpty() 
        select new { (list of fields) }; 
     foreach (TrackDocument tDoc in query) 
     { 
      this.Add(tDoc); 
     } 
    } 
} 

그러나이 작동하지 않습니다 같은 것을 : 내가 ObservableCollection에를 채우기 위해 여기에 생성자에서 LINQ 쿼리를 추가 한 다음 foreach 루프를 할 필요 나에게 발생 "원래 예외의 원인 인 dbml 레이아웃의 TrackDocument 클래스 속성 목록에 대한 저장 프로 시저에 대한 참조). . . 컴파일러는 어떤 이유로 쿼리 항목을 TrackDocument 클래스로 캐스팅을 조정할 수 없습니다.

일반 단일 테이블의 경우 TrackDocuemnts 컬렉션을 생성하는 쿼리를 실행하려면 TrackDocument 클래스에서 IDE 생성 메서드 중 하나를 재정의해야합니까? 그렇다면 무시 방법에 대한 예를 들어 주시겠습니까? 클래스 코드는 자동 생성 파일에 있으므로 수동으로 거기에 물건을 추가 할 수 없다는 것을 알고 있습니다. . .

분명히하는 것이 좋겠습니다. . . 나는 이런 것들을 설명하는 언어에 대해 혼란스러워합니다.

감사합니다, 폴

+0

System.Data.Linq.Mapping.FunctionAttribute를 사용하여 저장 프로 시저를 함수에 연결하려고한다고 생각합니다. – juharr

+0

@juharr DataContext에 저장 프로 시저를 디자이너 레이아웃으로 드래그하여 추가하는 것으로 해석합니다. . . 내가 한 일이다. 메서드로 나타나며 클래스의 비헤이비어와 연결할 수 있지만 삽입, 삭제 또는 업데이트로만 연결할 수 있습니다. designer.cs 파일을 수동으로 변경하면 IDE에서 자동으로 생성되므로 덮어 씁니다. 그래서 정확히 무슨 뜻인지 모르겠습니다. . . 죄송합니다 obtuse :) –

+0

@juharr 나는 줄을'[global :: System.Data.Linq.Mapping.FunctionAttribute (Name = "dbo.ListAllDocuments")]'로 변경하려고 시도했지만 컴파일러는 이것이 단지 방법에 적합합니다. . . –

답변

1

바울은

는보기 대신 저장 프로 시저를 사용하십시오. 이것은 Linq로 테이블과 같은 기능을 제공합니다.

저장 프로 시저를 사용해야하는 경우 데이터 집합이 반환되므로 저장 프로 시저의 반환 형식에 대한 엔터티를 만들어야합니다. DBML 디자이너에서 저장 프로 시저를 클릭하면 "반환 유형"(SPROC에서 반환 된 데이터를받을 클래스/테이블) 속성을 확인하십시오.

당신의 저장 프로 시저가 있다면 예를 들어, :

CREATE PROCEDURE sp_get_ObservableTrackDocuments 
    @documentNumber int 
AS 
BEGIN 
    SELECT A,B,C 
    FROM FilesTransmitted, FilesReturned 
    WHERE DocumentNumber = @documentNumber 
END 

당신은 뷰와 동일한 맥락 만들 수 있습니다

CREATE VIEW vw_ObservableTrackDocument 
AS 
BEGIN 
    SELECT A,B,C 
    FROM FilesTransmitted, FilesReturned 
END 

뷰는 드래그 할 수 및에 서버 탐색기에서 제외하여 dbml이며 테이블로 작동합니다. 당신이 코드에서 조회 할 수 있습니다이 방법 :

var otd = vw_ObservableTrackDocuments.Where(x => x.DocumentNumber = "123").ToList(); 

이 수동으로 Linq에 생성 된 코드를 조작 할 필요없이, 당신에게 DocumentNumber (123)에 의한 결과의 목록을 반환합니다.

+0

예를 들려 줄 수 있습니까? 나는 저장 프로 시저에 묶여 있지 않다. 사실 실제로 무엇이 일어나고 있는지에 대한 나의 이해를 발전시키지 않도록 명시 적으로 질의하는 방법을 찾는 것이 더 좋다. –

+0

내가 일한 것을 게시했습니다. . . 그것이 펼쳐질 지 확신하지 못합니다. SP를 사용하여 DataContext 테이블을 생성 할 수 없기 때문에 SP의 반환 유형도 변경했습니다. –

+1

Paul, 극도의 지연을 위해 유감스럽게 생각합니다. 귀하의 질문에 대한 답변을 희망적으로 명확히하기 위해 답변을 수정했습니다. SP와 관련하여 반환 유형은 SP에서 되돌아 오는 것을 반영해야합니다. SP가 Document, Name, Date, ...를 반환하면 Linq가 매핑 할 필드와 데이터 유형을 보유하는 엔티티를 추가해야합니다. GUI 디자이너에서> new> entity를 마우스 오른쪽 버튼으로 클릭하고 결과를 저장하는 사용자 정의 "테이블"을 생성 할 수 있습니다. 다시 말하지만 데이터 유형 문제가 발생할 수 있으므로 직접 매핑 할 수있는보기를 시도하는 것이 가장 좋습니다. –

0

이것은 내가 지금 무엇을하고, 노력하고 있습니다 :

class tdoc 
{ 
    public int xID {get; set;} 
    public int TransID { get; set; } 
    public System.String TransmittalName { get; set; } 
    public System.String FileName { get; set; } 
    public System.String DocumentNumber { get; set; } 
    public System.String REV { get; set; } 
    public System.DateTime REVDate { get; set; } 
    public System.String Title { get; set; } 
    public int? rID { get; set; } 
    public int? CODE { get; set; } 
    public System.String RTNTrans { get; set; } 
    public System.String RtnFile { get; set; } 
} 

class ObservableTrackDocument : ObservableCollection<TrackDocument> 
{ 
    public ObservableTrackDocument(DocControlClassesDataContext dataDc) 
    { 
     IEnumerable<tdoc> query = from f in dataDc.FilesTransmitteds 
              from r in dataDc.FilesReturneds 
              .Where(r => f.DocumentNumber == r.DocumentNumber && f.REV == r.REV) 
              .DefaultIfEmpty() 
              select new tdoc 
              { 
               xID = f.UID, 
               TransID = (int)f.TransID, 
               TransmittalName = f.TransmittalName, 
               FileName = f.FileName, 
               DocumentNumber = f.DocumentNumber, 
               REV = f.REV, 
               REVDate = (System.DateTime)f.REVDate, 
               Title = f.Title, 
               rID = r.UID, 
               CODE = r.CODE, 
               RTNTrans = r.RTNTrans, 
               RtnFile = r.FileName 
              }; 
     foreach (tdoc Doc in query) 
     { 
      TrackDocument d = new TrackDocument(); 
      d.xID = Doc.xID; 
      d.TransID = Doc.TransID; 
      d.TransmittalName = Doc.TransmittalName; 
      d.FileName = Doc.FileName; 
      d.DocumentNumber = Doc.DocumentNumber; 
      d.REV = Doc.REV; 
      d.REVDate = Doc.REVDate; 
      d.Title = Doc.Title; 
      d.rID = Doc.rID; 
      d.CODE = Doc.CODE; 
      d.RTNTrans = Doc.RTNTrans; 
      d.RtnFile = Doc.RtnFile; 
      this.Add(d); 
     } 
    } 
} 

내가 DataContext에의 일환으로 TrackDocument 클래스가 있습니다. 조인을 사용하려면 쿼리 할 DataContext 외부에 동등한 클래스를 생성해야합니다 (그렇지 않으면 "명시 적으로 생성 된 Entity Type xxx는 쿼리에서 허용되지 않습니다"예외). 그런 다음 내 observableCollection을 복사하여 채 웁니다. DataContext 클래스. 이것은 일종의 거꾸로 보인다. . . 더 좋은 방법이 없습니까?