C# WPF LINQ到SQL类自定义

C# WPF LINQ到SQL类自定义,c#,wpf,linq,C#,Wpf,Linq,我正在使用Visual Studio Express 2013和SQL Server Express 2014,编写一个使用LINQ to SQL访问数据的WPF应用程序。我的目的是提供完整的CRUD功能,使用映射到observableCollections的各种UI元素。到目前为止,一切正常,但我只是使用映射到datagrid的各个表。我想用两个表的左联接结果来表示一个datagrid,因此在dbml布局中,我创建了一个新表,并使用了一个存储过程,因为数据源IDE生成的代码如下所示: [glo

我正在使用Visual Studio Express 2013和SQL Server Express 2014,编写一个使用LINQ to SQL访问数据的WPF应用程序。我的目的是提供完整的CRUD功能,使用映射到observableCollections的各种UI元素。到目前为止,一切正常,但我只是使用映射到datagrid的各个表。我想用两个表的左联接结果来表示一个datagrid,因此在dbml布局中,我创建了一个新表,并使用了一个存储过程,因为数据源IDE生成的代码如下所示:

[global::System.Data.Linq.Mapping.TableAttribute(Name="dbo.ListAllDocuments")]
public partial class TrackDocument : INotifyPropertyChanging, INotifyPropertyChanged
{ // innards removed for readability }
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);
        }
    }
}
当我运行这个程序时,我得到一个未处理的异常“无效的对象名'dbo.ListAllDocuments'”。这是带有左Join语句的存储过程。如何将查询语言添加到为表示此数据而构建的类中?以下是我使用单表案例建模的带构造函数的可观察类,用于最终绑定到UI:

class ObservableTrackDocument : ObservableCollection<TrackDocument>
{
    public ObservableTrackDocument(DocControlClassesDataContext dataDc)
    {
        foreach (TrackDocument tDoc in dataDc.TrackDocuments)
        {
            this.Add(tDoc);
        }
    }
}
类ObservableTrackDocument:ObservableCollection
{
公共ObservableTrackDocument(DocControlClassesDataContext dataDc)
{
foreach(dataDc.TrackDocuments中的TrackDocument tDoc)
{
添加(tDoc);
}
}
}
但是没有为表填充datacontext,因为存储过程不能用作源。我突然想到,我需要在这里的构造函数中添加LINQ查询,然后执行foreach循环来填充observableCollection:类似这样:

[global::System.Data.Linq.Mapping.TableAttribute(Name="dbo.ListAllDocuments")]
public partial class TrackDocument : INotifyPropertyChanging, INotifyPropertyChanged
{ // innards removed for readability }
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);
        }
    }
}
类ObservableTrackDocument:ObservableCollection
{
公共ObservableTrackDocument(DocControlClassesDataContext dataDc)
{
var query=来自dataDc.FilesTransmitteds中的f
从dataDc.files中的r返回
其中(x=>f.DocumentNumber==x.DocumentNumber&&f.REV==x.REV)
.DefaultIfEmpty()
选择新{(字段列表)};
foreach(查询中的跟踪文档时差)
{
添加(tDoc);
}
}
}
但这也不起作用(我记得dbml布局中TrackDocument类属性列表的存储过程的“Source”引用是原始异常的原因)。由于某些原因,编译器无法将查询项转换为TrackDocument类

我是否需要重写TrackDocument类中IDE生成的方法之一,以执行在普通单表情况下会导致TrackDocuemnts集合的查询?如果是这样,你能给我一个如何覆盖的例子吗?类代码位于自动生成的文件中,因此我知道无法手动在其中添加内容

我希望这是清楚的。我对描述这些东西的语言感到困惑

谢谢你,保罗

尝试使用视图而不是存储过程。这将为您提供Linq的类似于表的功能

如果必须使用存储过程(即返回数据集),则需要为存储过程的返回类型创建一个实体。单击DBML设计器中的存储过程时,请检查“返回类型”的属性(这是将接收存储过程返回的数据的类/表)

例如,如果存储过程是:

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生成的代码。

这就是我现在拥有的,并且正在工作:

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);
        }
    }
}
class-tdoc
{
公共int xID{get;set;}
公共int TransID{get;set;}
public System.String TransmittalName{get;set;}
public System.String文件名{get;set;}
public System.String DocumentNumber{get;set;}
public System.String REV{get;set;}
public System.DateTime REVDate{get;set;}
public System.String标题{get;set;}
公共int?rID{get;set;}
公共int?代码{get;set;}
public System.String RTNTrans{get;set;}
public System.String RtnFile{get;set;}
}
类ObservableTrackDocument:ObservableCollection
{
公共ObservableTrackDocument(DocControlClassesDataContext dataDc)
{
IEnumerable query=来自dataDc.FilesTransmitteds中的f
从dataDc.files中的r返回
其中(r=>f.DocumentNumber==r.DocumentNumber&&f.REV==r.REV)
.DefaultIfEmpty()
选择新时差
{
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,
代码=r代码,
RTNTrans=r.RTNTrans,
RtnFile=r.FileName
};
foreach(查询中的tdoc单据)
{
TrackDocument d=新的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、 转载日期=