当前位置:首页 » 编程语言 » linq2sql
扩展阅读
webinf下怎么引入js 2023-08-31 21:54:13
堡垒机怎么打开web 2023-08-31 21:54:11

linq2sql

发布时间: 2022-07-25 20:58:44

‘壹’ 如何直接执行sql语句

1、ExecuteQuery方法

看命名,我们很容易联想到ADO.NET里熟悉的Command的ExecuteNonQuery方法,但是VS的智能提示告诉我们这个方法返回的是一个泛型集合,应该“所思非所得”。下面通过一个简单方法,验证我们的猜想(数据库设计可以参考这一篇):

/// <summary>
/// 直接执行sql语句,获取总人数
/// </summary>
/// <returns></returns>
publicint GetTotalCount()
{
string strSql = "SELECT COUNT(0) FROM Person(NOLOCK)";
var query = dataContext.ExecuteQuery<int>(strSql);
int result = query.First<int>();
Console.WriteLine();
Console.WriteLine("total count:{0}", result);
return result;
}

调试的时候,通过IntelliTrace跟踪到:

毫无疑问,上面的图片说明最初的想法是不正确的,”ADO.NET:执行Reader…”云云,让我们更加坚信它实际执行的应该是ExecuteReader方法。当然最简单的方法是直接查看它的方法说明:

// 摘要:
// 直接对数据库执行 SQL 查询并返回对象。
//
// 参数:
// query:
// 要执行的 SQL 查询。
//
// parameters:
// 要传递给命令的参数数组。注意下面的行为:如果数组中的对象的数目小于命令字符串中已标识的最大数,
则会引发异常。如果数组包含未在命令字符串中引用的对象,则不会引发异常。如果某参数为
// null,则该参数会转换为 DBNull.Value。
//
// 类型参数:
// TResult:
// 返回的集合中的元素的类型。
//
// 返回结果:
// 由查询返回的对象的集合。
public IEnumerable<TResult> ExecuteQuery<TResult>(string query, paramsobject[] parameters);

ExecuteQuery方法还有一个非泛型方法:

//
// 摘要:
// 直接对数据库执行 SQL 查询。
//
// 参数:
// elementType:
//

要返回的 System.Collections.Generic.IEnumerable<T>
的类型。使查询结果中的列与对象中的字段或属性相匹配的算法如下所示:如果字段或属性映射到特定列名称,则结果集中应包含该列名称。如果未映射字段或属性,则结果集中应包含其名称与该字段或属性相同的列。通过先查找区分大小写的匹配来执行比较。如果未找到匹配项,则会继续搜索不区分大小写的匹配项。如果同时满足下列所有条件,则该查询应当返回(除延迟加载的对象外的)对象的所有跟踪的字段和属性:T

// 是由 System.Data.Linq.DataContext 显式跟踪的实体。
System.Data.Linq.DataContext.ObjectTrackingEnabled
// 为 true。实体具有主键。否则会引发异常。
//
// query:
// 要执行的 SQL 查询。
//
// parameters:
// 要传递给命令的参数数组。注意下面的行为:如果数组中的对象的数目小于命令字符串中已标识的最大数,
则会引发异常。如果数组包含未在命令字符串中引用的对象,则不会引发异常。如果某参数为
// null,则该参数会转换为 DBNull.Value。
//
// 返回结果:
// 由查询返回的对象的 System.Collections.Generic.IEnumerable<T> 集合。
public IEnumerable ExecuteQuery(Type elementType, string query, paramsobject[] parameters);

看它的参数需要多传递一个elementType,明显不如泛型方法简洁。

2、ExecuteCommand方法

同样道理,这个方法立刻让我们联想到(世界没有联想,生活将会怎样?),联想到,等等,不知联想到什么。然后我们看一下方法使用说明:

//
// 摘要:
// 直接对数据库执行 SQL 命令。
//
// 参数:
// command:
// 要执行的 SQL 命令。
//
// parameters:
// 要传递给命令的参数数组。注意下面的行为:如果数组中的对象的数目小于命令字符串中已标识的最大数,
则会引发异常。如果数组包含未在命令字符串中引用的对象,则不会引发异常。如果任一参数为
// null,则该参数会转换为 DBNull.Value。
//
// 返回结果:
// 一个 int,表示所执行命令修改的行数。
publicint ExecuteCommand(string command, paramsobject[] parameters);

到这里,看它的返回类型为int,表示执行命令修改的行数,这次很容易想到ExecuteNonQuery方法。对不对呢?通过下面的代码证明我们的设想:

/// <summary>
/// 直接执行sql语句 根据用户Id更新体重
/// </summary>
/// <param name="id">用户Id</param>
/// <param name="destWeight">更新后的体重</param>
/// <returns></returns>
publicint ModifyWeightById(int id, double destWeight)
{
string strSql = string.Format("UPDATE Person SET Weight={0} WHERE Id={1}", destWeight, id);
int result = dataContext.ExecuteCommand(strSql);
Console.WriteLine();
Console.WriteLine("affect num:{0}", result);
return result;
}

调试过程中,通过IntelliTrace可以很清楚地捕获:“ADO.NET:执行NonQuery…”基本可以断言我们的设想是正确的。

3、防止sql注入

1和2中,执行sql语句的两个方法都有一个params 类型的参数,我们又会想到ADO.NET非常重要的sql语句的参数化防止sql注入问题。下面通过一个方法,看看linq2sql可不可以防止sql注入。

(1)、直接执行拼接的sql语句(有风险)

/// <summary>
/// 直接执行sql语句 根据用户Id更新FirstName
/// </summary>
/// <param name="id">用户Id</param>
/// <param name="destName">更新后的FirstName</param>
/// <returns></returns>
publicint ModifyNameById(int id, string destName)
{
string strSql = string.Format("UPDATE Person SET FirstName='{0}' WHERE Id={1}", destName, id);
//这么拼接有风险
int result = dataContext.ExecuteCommand(strSql);
Console.WriteLine();
Console.WriteLine("affect num:{0}", result);
return result;
}

然后,在客户端这样调用这个方法:

int result = ServiceFactory.CreatePersonService().ModifyNameById(10, "'Anders'");
//更新id为10的人的FirstName

‘贰’ sql 函数 exec在c#linq怎么写

linq2sql?
你在linq2sql的操作界面把函数或者过程拖到里面就可以了。
使用的话,你实例linq2sql,直接点出来用就行。跟平时调用函数一样。

‘叁’ 听说net3.5中新出来Linq不知道什么用处

LINQ还是LINQ2SQL?
LINQ是一种新型的集成性查询语言,可以用接近自然语言的方式来在集合中查询数据。比如: from p in objArray where p.StartsWith("a")

LINQ2SQL是一个ORM框架,用于对数据库中的数据映射到具体的实体,减轻在数据库层需要做的工作,提高开发效率。

具体的,可以搜索相关网页,现在这个东西很多了,楼主不要太懒的说~~

‘肆’ linq to sql 的删除一张表中的多条记录

Linq2Sql本身没有这样的方法,但是网上有人扩展出了这样的方法.
不过这样的语句,本身可以通过Linq2Sql直接执行SQL或存储过程来解决,更加灵活.

‘伍’ Linq to sql可以和Oracle一起使用吗

可以,Oracle官网去下载一个Developer Tools for Visual Studio就可以了
地址:http://www.oracle.com/technetwork/database/windows/downloads/index-101290.html

‘陆’ linqtosql动态生成的表加不加s

在自动生成的DataContext中有Students属性,它的类型是Table<Student>对应数据库中的Student表,我们的查询对象就是它了。
先来一个最简单的Query

1
2

var query = from s in db.Students
select s;

上面的语句可以查询Student表的所有记录,但是它却不同于 SQL语句

1
2
3
4
5
6
7
8
9
10

SELECT [StudentID]
,[Name]
,[Hometown]
,[Gender]
,[Birthday]
,[ClassID]
,[WeightInKg]
,[HeightInCm]
,[Desc]
FROM [Test].[dbo].[Student]

query的数据类型是IQueryable<Student> ,其字面意思是Student的可查询实例,通过这个query我们可以做很多种查询,当然包括上面的SQL语句。具体这个IQueryable实例会做那种查询和我们后续代码中如何使用它有关系,下面是几个例子:
1. 使用query返回Student表中的记录数,代码如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14

using (var writer = new StreamWriter(@"E:\projects.2010\Test\LINQ2SQL_2\linq.sql", false, Encoding.UTF8))
{
//最简单的select
using (DbAppDataContext db = new DbAppDataContext())
{
//设置Log打印到的地方
db.Log = writer;
var query = from s in db.Students
select s;

//返回Student表中的记录数
var cn = query.Count();
}
}

上面query.Count()执行的SQL如下:

1
2
3

SELECT COUNT(*) AS [value]
FROM [dbo].[Student] AS [t0]
-- Context: SqlProvider(Sql2005) Model: AttributedMetaModel Build: 4.0.30319.

生成的sql语句很规范,取得Student表中的记录数
2.给这个IQuerable添加条件身高大于130cm,然后执行查询

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

using (var writer = new StreamWriter(@"E:\projects.2010\Test\LINQ2SQL_2\linq.sql", false, Encoding.UTF8))
{
//最简单的select
using (DbAppDataContext db = new DbAppDataContext())
{
//设置Log属性,将生成的sql语句保存到文件中
db.Log = writer;
var query = from s in db.Students
select s;

//打印身高大于132cm的Student
foreach (var item in query.Where(s => s.HeightInCm > 132))
{
Console.WriteLine("{0}的身高是{1}cm", item.Name, item.HeightInCm);
}
}
}

其SQL语句如下:可以看到linq to sql对sql注入攻击有天然的免疫作用,它自动生成的sql语句是参数化的

1
2
3
4
5

SELECT [t0].[StudentID], [t0].[Name], [t0].[Hometown], [t0].[Gender], [t0].[Birthday], [t0].[ClassID], [t0].[WeightInKg], [t0].[HeightInCm], [t0].[Desc] AS [Desc]
FROM [dbo].[Student] AS [t0]
WHERE [t0].[HeightInCm] > @p0
-- @p0: Input Float (Size = -1; Prec = 0; Scale = 0) [132]
-- Context: SqlProvider(Sql2005) Model: AttributedMetaModel Build: 4.0.30319.1

我们可以对IQueryable附加条件限制,其实添加这个Where后的query和下面的语句是等价的。

1
2
3

var query = from s in db.Students
where s.HeightInCm > 132
select s;

那么如果我们的query实例中已经有条件后再加限制会是什么样子的呢,请看3
3. 在query定义是有身高、体重两个查询条件,在使用query时我们又附加了一个Hometown在“多家营”的条件,看下代码和真实执行的sql情况

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

using (var writer = new StreamWriter(@"E:\projects.2010\Test\LINQ2SQL_2\linq.sql", false, Encoding.UTF8))
{
//最简单的select
using (DbAppDataContext db = new DbAppDataContext())
{
//设置Log属性,将生成的sql语句保存到文件中
db.Log = writer;

//查询身高大于132并且体重大于30的Student
var query = from s in db.Students
where s.HeightInCm > 132 && s.WeightInKg > 30
select s;

//在query中用Where附加家乡在多家营的记录
foreach (var item in query.Where(s => s.Hometown == "多家营"))
{
Console.WriteLine("{0}的身高是{1}cm", item.Name, item.HeightInCm);
}
}
}

SQL:

1
2
3
4
5
6
7

SELECT [t0].[StudentID], [t0].[Name], [t0].[Hometown], [t0].[Gender], [t0].[Birthday], [t0].[ClassID], [t0].[WeightInKg], [t0].[HeightInCm], [t0].[Desc] AS [Desc]
FROM [dbo].[Student] AS [t0]
WHERE <span style="background-color: #ffff00;">([t0].[Hometown] = @p0)</span> AND ([t0].[HeightInCm] > @p1) AND ([t0].[WeightInKg] > @p2)
-- @p0: Input NVarChar (Size = 4000; Prec = 0; Scale = 0) [多家营]
-- @p1: Input Float (Size = -1; Prec = 0; Scale = 0) [132]
-- @p2: Input Float (Size = -1; Prec = 0; Scale = 0) [30]
-- Context: SqlProvider(Sql2005) Model: AttributedMetaModel Build: 4.0.30319.1

可以看出后附件的条件并非如我们常规理解附件到条件的最后,而是放到了最前面,这一点有可能对效率造成影响,是需要我们注意的。
通过上面三点可以看出来linq to sql中的IQueryable并非等同于某一个sql语句,其具体要执行的sql语句和具体情况有关系。
在query定义时可以很方便的添加排序规则,可以是一个或者n个,如下语句:

1
2
3
4
5

//查询身高大于132并且体重大于30的Student,并按照StudentID升序排序,按照classID降序排序
var query = from s in db.Students
where s.HeightInCm > 132 && s.WeightInKg > 30
orderby s.StudentID ascending, s.ClassID descending
select s;

‘柒’ VS2008 单元测试问题

VS2008中不能为Linq2Sql这种数据库访问模块使用单元测试向导。
不过,你可以把逻辑尽可能的分拆,把尽可能多的逻辑从使用Linq2sql的DA层中转移到其他的工程中。

单元测试两大公认不可测功能就是DA和UI

‘捌’ linq to sql any和all的区别

Linq是微软在.net3.0推出的一种新的数据访问和处理的方式,来解决过去处理集合对象数据所遇到的种种困难。其中在C#3.0和VB9中分别引入了和SQL相似的Linq语法,使得现在操作各种数据对象变得非常容易而且可读性更好。

Linq To Sql是微软默认提供的LinqProvider的一种,其他的还有LinqToDataSet LinqToXml LinqToEntity等。

平时开发项目可以大量的使用linq,他会让你在处理大量集合数据的时候提高效率。而Linq2Sql算是一个ORM框架,可以用来减轻数据访问的负担,如果你知道Hibernate之类的ORM框架的话,就很容易理解他了

‘玖’ 如何查看linq生成的sql

如何查看linq生成的sql
class table
{
public string id
}

private void Window_Loaded(object sender, RoutedEventArgs e)
{
List<table> ls = new List<table>();
for (int i = 0; i < 10; i++)
ls.Add(new table );

int pageSize = 3;
int currentPage = 2;

var linq = (from t in ls.ToArray()
where
(from t2 in ls.ToArray() select t2.id).Take(pageSize * (currentPage - 1)).ToArray().Contains(t.id) == false
select t).Take(pageSize);

foreach (var l in linq)
this.Title += l.id + ",";
}

‘拾’ Linq和LinqtoSql有什么区别一般做项目用哪种

Linq是微软在.net3.0推出的一种新的数据访问和处理的方式,来解决过去处理集合对象数据所遇到的种种困难。其中在C#3.0和VB9中分别引入了和SQL相似的Linq语法,使得现在操作各种数据对象变得非常容易而且可读性更好。

Linq To Sql是微软默认提供的LinqProvider的一种,其他的还有LinqToDataSet LinqToXml LinqToEntity等。

平时开发项目可以大量的使用linq,他会让你在处理大量集合数据的时候提高效率。而Linq2Sql算是一个ORM框架,可以用来减轻数据访问的负担,如果你知道Hibernate之类的ORM框架的话,就很容易理解他了