『壹』 如何直接執行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框架的話,就很容易理解他了