linqtosql视图存储过程.docx
- 文档编号:25089276
- 上传时间:2023-06-05
- 格式:DOCX
- 页数:37
- 大小:70.71KB
linqtosql视图存储过程.docx
《linqtosql视图存储过程.docx》由会员分享,可在线阅读,更多相关《linqtosql视图存储过程.docx(37页珍藏版)》请在冰豆网上搜索。
linqtosql视图存储过程
使用LINQ进行多表操作
(一)
有时候我们需要对多张数据表进行一次性的Select操作。
目前就我所知的操作方法有三种:
1.直接写表达式;2.使用LoadOption选项;3.使用Join语句。
那么,这三种语句用哪一种好呢?
让我们来做一个小小的研究。
。
呱呱。
。
1:
1关系的多表操作
表结构如下
首先是测试取全记录的情况(也就是取所有字段)
直接写表达式
var user = context.Users.Where(p => p.UserID == 10300).Select(p => new {p, p.UserData});
SELECT [t0].[UserID], [t0].[Email], [t0].[NickName], [t2].[test], [t2].[UserID] AS [UserID2], [t2].[MyInfo], [t2].[MyFriends] FROM [dbo].[Users] AS [t0] LEFT OUTER JOIN (SELECT 1 AS [test], [t1].[UserID], [t1].[MyInfo], [t1].[MyFriends] FROM [dbo].[UserData] AS [t1]) AS [t2] ON [t2].[UserID] = [t0].[UserID]WHERE [t0].[UserID] = 10300
使用LoadOption选项
var option = new DataLoadOptions();
option.LoadWith
context.LoadOptions = option;
var user = context.Users.Where(p => p.UserID == 10300).Single();
var userdata = user.UserData;
虽然看上去取了2次数据,但是因为指定了LoadOption选项,所以也是一次性从数据库取出来的。
SELECT [t0].[UserID], [t0].[Email], [t0].[NickName], [t2].[test], [t2].[UserID] AS [UserID2], [t2].[MyInfo], [t2].[MyFriends] FROM [dbo].[Users] AS [t0]
LEFT OUTER JOIN (SELECT 1 AS [test], [t1].[UserID], [t1].[MyInfo], [t1].[MyFriends] FROM [dbo].[UserData] AS [t1]) AS [t2] ON [t2].[UserID] = [t0].[UserID]
WHERE [t0].[UserID] = 10300
使用Join语句
var user = context.Users.Where(p => p.UserID == 10300).Join(context.UserDatas, p => p.UserID, o => o.UserID, (o, p) => new { o, p });
SELECT [t0].[UserID], [t0].[Email], [t0].[NickName], [t1].[UserID] AS [UserID2], [t1].[MyInfo], [t1].[MyFriends] FROM [dbo].[Users] AS [t0] INNER JOIN [dbo].[UserData] AS [t1] ON [t0].[UserID] = [t1].[UserID] WHERE [t0].[UserID] = 10300
但是要注意的一点是,如果用了.Select(p=>new{p,p.UserData})这种代码,你在使用实体的时候会稍微麻烦一点,要采用user.p.UserID这种形式,非常不爽。
可以这样改进一下,写成.Select(p=>new{User=p,p.UserData})这种形式,这样的话可以使用user.User.UserID来访问。
如果想直接用user.UserID来访问的话,就必须在new的时候为每一个属性赋名称,如果数据表字段很多的话,那我只能恭喜你中奖啦。
如果要我评分的话,我会这样评
SQL代码
C#Select代码
返回实例的易用性
直接写表达式
低
高
中
使用LoadOption
低
低
高
使用Join语句
高
中
中
如果只是要取部分字段的话,我们必须在Select的时候指定要取的字段,这样的话,在返回实例的易用性上,三种方式将是一样的效果。
SQL代码
C#Select代码
返回实例的易用性
直接写表达式
低
高
高
使用LoadOption
低
低
高
使用Join语句
高
中
高
LINQtoSQL语句之存储过程
存储过程
在我们编写程序中,往往需要一些存储过程,在LINQtoSQL中怎么使用呢?
也许比原来的更简单些。
下面我们以NORTHWND.MDF数据库中自带的几个存储过程来理解一下。
1.标量返回
在数据库中,有名为CustomersCountByRegion的存储过程。
该存储过程返回顾客所在"WA"区域的数量。
ALTERPROCEDURE[dbo].[NonRowset]
(@param1NVARCHAR(15))
AS
BEGIN
SETNOCOUNTON;
DECLARE@countint
SELECT@count=COUNT(*)FROMCustomers
WHERECustomers.Region=@Param1
RETURN@count
END
我们只要把这个存储过程拖到O/R设计器内,它自动生成了以下代码段:
[Function(Name="dbo.[CustomersCountByRegion]")]
publicintCustomers_Count_By_Region([Parameter
(DbType="NVarChar(15)")]stringparam1)
{
IExecuteResultresult=this.ExecuteMethodCall(this,
((MethodInfo)(MethodInfo.GetCurrentMethod())),param1);
return((int)(result.ReturnValue));
}
我们需要时,直接调用就可以了,例如:
intcount=db.CustomersCountByRegion("WA");
Console.WriteLine(count);
语句描述:
这个实例使用存储过程返回在“WA”地区的客户数。
2.单一结果集
从数据库中返回行集合,并包含用于筛选结果的输入参数。
当我们执行返回行集合的存储过程时,会用到结果类,它存储从存储过程中返回的结果。
下面的示例表示一个存储过程,该存储过程返回客户行并使用输入参数来仅返回将“London”列为客户城市的那些行的固定几列。
ALTERPROCEDURE[dbo].[CustomersByCity]
--Addtheparametersforthestoredprocedurehere
(@param1NVARCHAR(20))
AS
BEGIN
--SETNOCOUNTONaddedtopreventextraresultsetsfrom
--interferingwithSELECTstatements.
SETNOCOUNTON;
SELECTCustomerID,ContactName,CompanyName,Cityfrom
Customersascwherec.City=@param1
END
拖到O/R设计器内,它自动生成了以下代码段:
[Function(Name="dbo.[CustomersByCity]")]
publicISingleResult
[Parameter(DbType="NVarChar(20)")]stringparam1)
{
IExecuteResultresult=this.ExecuteMethodCall(this,(
(MethodInfo)(MethodInfo.GetCurrentMethod())),param1);
return((ISingleResult
(result.ReturnValue));
}
我们用下面的代码调用:
ISingleResult
db.Customers_By_City("London");
foreach(Customers_By_CityResultcustinresult)
{
Console.WriteLine("CustID={0};City={1}",cust.CustomerID,
cust.City);
}
语句描述:
这个实例使用存储过程返回在伦敦的客户的CustomerID和City。
3.多个可能形状的单一结果集
当存储过程可以返回多个结果形状时,返回类型无法强类型化为单个投影形状。
尽管LINQtoSQL可以生成所有可能的投影类型,但它无法获知将以何种顺序返回它们。
ResultTypeAttribute属性适用于返回多个结果类型的存储过程,用以指定该过程可以返回的类型的集合。
在下面的SQL代码示例中,结果形状取决于输入(param1=1或param1=2)。
我们不知道先返回哪个投影。
ALTERPROCEDURE[dbo].[SingleRowset_MultiShape]
--Addtheparametersforthestoredprocedurehere
(@param1int)
AS
BEGIN
--SETNOCOUNTONaddedtopreventextraresultsetsfrom
--interferingwithSELECTstatements.
SETNOCOUNTON;
if(@param1=1)
SELECT*fromCustomersascwherec.Region='WA'
elseif(@param1=2)
SELECTCustomerID,ContactName,CompanyNamefrom
Customersascwherec.Region='WA'
END
拖到O/R设计器内,它自动生成了以下代码段:
[Function(Name="dbo.[WholeOrPartialCustomersSet]")]
publicISingleResult
Whole_Or_Partial_Customers_Set([Parameter(DbType="Int")]
System.Nullable
{
IExecuteResultresult=this.ExecuteMethodCall(this,
((MethodInfo)(MethodInfo.GetCurrentMethod())),param1);
return((ISingleResult
(result.ReturnValue));
}
但是,VS2008会把多结果集存储过程识别为单结果集的存储过程,默认生成的代码我们要手动修改一下,要求返回多个结果集,像这样:
[Function(Name="dbo.[WholeOrPartialCustomersSet]")]
[ResultType(typeof(WholeCustomersSetResult))]
[ResultType(typeof(PartialCustomersSetResult))]
publicIMultipleResultsWhole_Or_Partial_Customers_Set([Parameter
(DbType="Int")]System.Nullable
{
IExecuteResultresult=this.ExecuteMethodCall(this,
((MethodInfo)(MethodInfo.GetCurrentMethod())),param1);
return((IMultipleResults)(result.ReturnValue));
}
我们分别定义了两个分部类,用于指定返回的类型。
WholeCustomersSetResult类如下:
(点击展开)
代码在这里展开
publicpartialclassWholeCustomersSetResult
{
privatestring_CustomerID;
privatestring_CompanyName;
privatestring_ContactName;
privatestring_ContactTitle;
privatestring_Address;
privatestring_City;
privatestring_Region;
privatestring_PostalCode;
privatestring_Country;
privatestring_Phone;
privatestring_Fax;
publicWholeCustomersSetResult()
{
}
[Column(Storage="_CustomerID",DbType="NChar(5)")]
publicstringCustomerID
{
get{returnthis._CustomerID;}
set
{
if((this._CustomerID!
=value))
this._CustomerID=value;
}
}
[Column(Storage="_CompanyName",DbType="NVarChar(40)")]
publicstringCompanyName
{
get{returnthis._CompanyName;}
set
{
if((this._CompanyName!
=value))
this._CompanyName=value;
}
}
[Column(Storage="_ContactName",DbType="NVarChar(30)")]
publicstringContactName
{
get{returnthis._ContactName;}
set
{
if((this._ContactName!
=value))
this._ContactName=value;
}
}
[Column(Storage="_ContactTitle",DbType="NVarChar(30)")]
publicstringContactTitle
{
get{returnthis._ContactTitle;}
set
{
if((this._ContactTitle!
=value))
this._ContactTitle=value;
}
}
[Column(Storage="_Address",DbType="NVarChar(60)")]
publicstringAddress
{
get{returnthis._Address;}
set
{
if((this._Address!
=value))
this._Address=value;
}
}
[Column(Storage="_City",DbType="NVarChar(15)")]
publicstringCity
{
get{returnthis._City;}
set
{
if((this._City!
=value))
this._City=value;
}
}
[Column(Storage="_Region",DbType="NVarChar(15)")]
publicstringRegion
{
get{returnthis._Region;}
set
{
if((this._Region!
=value))
this._Region=value;
}
}
[Column(Storage="_PostalCode",DbType="NVarChar(10)")]
publicstringPostalCode
{
get{returnthis._PostalCode;}
set
{
if((this._PostalCode!
=value))
this._PostalCode=value;
}
}
[Column(Storage="_Country",DbType="NVarChar(15)")]
publicstringCountry
{
get{returnthis._Country;}
set
{
if((this._Country!
=value))
this._Country=value;
}
}
[Column(Storage="_Phone",DbType="NVarChar(24)")]
publicstringPhone
{
get{returnthis._Phone;}
set
{
if((this._Phone!
=value))
this._Phone=value;
}
}
[Column(Storage="_Fax",DbType="NVarChar(24)")]
publicstringFax
{
get{returnthis._Fax;}
set
{
if((this._Fax!
=value))
this._Fax=value;
}
}
}
PartialCustomersSetResult类如下:
(点击展开)
代码在这里展开
publicpartialclassPartialCustomersSetResult
{
privatestring_CustomerID;
privatestring_ContactName;
privatestring_CompanyName;
publicPartialCustomersSetResult()
{
}
[Column(Storage="_CustomerID",DbType="NChar(5)")]
publicstringCustomerID
{
get{returnthis._CustomerID;}
set
{
if((this._CustomerID!
=value))
this._CustomerID=value;
}
}
[Column(Storage="_ContactName",DbType="NVarChar(30)")]
publicstringContactName
{
get{returnthis._ContactName;}
set
{
if((this._ContactName!
=value))
this._ContactName=value;
}
}
[Column(Storage="_CompanyName",DbType="NVarChar(40)")]
publicstringCompanyName
{
get{returnthis._CompanyName;}
set
{
if((this._CompanyName!
=value))
this._CompanyName=value;
}
}
}
这样就可以使用了,下面代码直接调用,分别返回各自的结果集合。
//返回全部Customer结果集
IMultipleResultsresult=db.Whole_Or_Partial_Customers_Set
(1);
IEnumerable
result.GetResult
foreach(WholeCustomersSetResultcompNameinshape1)
{
Console.WriteLine(compName.CompanyName);
}
//返回部分Customer结果集
result=db.Whole_Or_Partial_Customers_Set
(2);
IEnumerable
result.GetResult
foreach(PartialCustomersSetResultconinshape2)
{
Console.WriteLine(con.ContactName);
}
语句描述:
这个实例使用存储过程返回“WA”地区中的一组客户。
返回的结果集形状取决于传入的参数。
如果参数等于1,则返回所有客户属性。
如果参数等于2,则返回ContactName属性。
4.多个结果集
这种存储过程可以生成多个结
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- linqtosql 视图 存储 过程