2014-11-06 80 views
0

我正在使用Visual Studio Express 2013和SQL Server Express 2014編寫一個使用LINQ to SQL來訪問數據的WPF應用程序。我的意圖是完整的CRUD功能,使用映射到observableCollections的各種UI元素。到目前爲止,一切正常,但我只是使用映射到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); 
     } 
    } 
} 

但DataContext的未填充的表,因爲該存儲過程不能用作源。它發生,我認爲我需要在構造在這裏添加LINQ查詢,然後執行foreach循環來填補的ObservableCollection:是這樣的:

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); 
     } 
    } 
} 

但是,這並不工作,要麼(我remvove「源「引用了原始異常原因的dbml佈局中的TrackDocument類屬性列表的存儲過程)。 。 。出於某種原因,編譯器無法協調將查詢項目轉換爲TrackDocument類。

我是否需要重寫TrackDocument類中IDE生成的方法之一以執行普通單表格情況下會導致TrackDocuemnts集合的查詢?如果是這樣,你能給我一個如何重寫的例子嗎?類代碼在自動生成的文件中,所以我知道我不能在那裏手動添加東西。 。 。

我希望這很清楚。 。 。我很困惑這種語言來描述這些事情。

謝謝,保羅

+0

我想你會想要將存儲過程與使用System.Data.Linq.Mapping.FunctionAttribute的函數相關聯。 – juharr 2014-11-06 18:54:20

+0

@juharr我通過將存儲過程拖放到設計器佈局中來解釋你所說的將存儲過程添加到DataContext中。 。 。我已經完成了。它顯示爲一種方法,可以與類的行爲相關聯,但只能作爲插入,刪除或更新。如果我手動更改designer.cs文件,那麼它將被覆蓋,因爲它是由IDE自動生成的。所以我不確定你的意思。 。 。對不起:) :) – 2014-11-06 19:12:48

+0

@juharr我試圖把行改成'[global :: System.Data.Linq.Mapping.FunctionAttribute(Name =「dbo.ListAllDocuments」)]'但編譯器告訴我這只是適用於方法。 。 。 – 2014-11-06 21:04:09

回答

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(); 

這將返回您的結果通過DocumentNumber 123的列表,而無需手動操作的LINQ生成的代碼。

+0

你能舉個例子嗎?我沒有被綁定到存儲過程,實際上認爲找到一種明確查詢的方式會更好,以免爲了發展我對實際正在發生的事情的理解。 – 2014-11-06 20:53:55

+0

我發佈了我的工作。 。 。不確定它會被淘汰。但是我也改變了SP的返回類型,但無濟於事,因爲我仍然無法使用SP創建DataContext表。 – 2014-11-07 00:23:41

+1

保羅,抱歉,極端延遲...值班電話。我修改了我的回覆,希望能夠澄清您的問題。關於SP,返回類型必須反映SP返回的內容。如果您的SP返回Document,Name,Date,...,那麼您必須添加一個實體來存放Linq要映射到的這些字段和數據類型。在GUI設計器中,您可以右鍵單擊>新建>實體並生成一個自定義「表格」來保存結果。這又會導致數據類型問題,所以最好的辦法是嘗試一個可以直接映射的視圖。 – 2014-11-24 15:23:31

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); 
     } 
    } 
} 

我有一個TrackDocument類作爲在DataContext的一部分。爲了查詢連接,我不得不在DataContext之外創建一個平等的類來查詢(否則我得到一個「顯式構造實體類型xxx不允許在查詢中」異常),然後我複製並填充我的observableCollection與DataContext類。這似乎有些倒退。 。 。沒有更好的方法嗎?