前些时间用LINQ to SQL做了一些项目,现在打算总结一下,帮助新手快速入门,并写一些别的教程没提到的东西。

一、LINQ to SQL和别的LINQ to XXX有什么关系?
二、延迟执行(Deferred Loading)
三、什么是LINQ to SQL?
四,看看LINQ to SQL到底干了些啥?——创建自己的工具类
五、创建一个基本查询
六,大致扫一扫
    1,WHERE
    2,DISTINCT
    3,AVG/COUNT/SUM/MIN/MAX
    4,GROUP BY
    5,CASE WHEN
    6,INNER JOIN和OUTER JOIN
        6.1 內连接
        6.2 外连接
    7,ORDER BY
    8,EXISTS
    9,WHERE IN
    10,UNION ALL/UNION
    11,Intersect/Except
    12,Skip-Take
    13,直接执行SQL语句查询
    14,INSERT
    15,UPDATE
    16,DELETE
    17,First/FirstOrDefault/Single
    18,字符串操作
七、查询条件拼接
八、自动事务处理
九、关于自增的ID字段
十、关于默认值
总结

一、LINQ to SQL和别的LINQ to XXX有什么关系?

我们能接触到的别的带有“LINQ”字眼的东西有:LINQ to Object和LINQ to Entity Framework。它们之间的关系可以说:除了使用了相似的语法,就没什么关系了。

LINQ to Object使用的命名空间是:System.Linq,而LINQ to SQL使用的命名空间是System.Data.Linq。

这是一个简单的LINQ to Object的例子:

        static IEnumerable<int> FindGreaterThan5(IEnumerable<int> list)
{
foreach (var i in list)
{
if (i >= )
yield return i;
}
} static void Main(string[] args)
{
List<int> listTest = new List<int>{ , , , , , , , }; //找出所有大于等于5的数
IEnumerable<int> result = FindGreaterThan5(listTest);
foreach (var i in result)
{
Console.WriteLine(i);
}
}

其中FindGreaterThan5的代码可以用LINQ to Object改为:

        static IEnumerable<int> FindGreaterThan5(IEnumerable<int> list)
{
return list.Where(i => i >= );
}

执行的效果是完全一样的,但要注意一点:LINQ to Object只是简化了代码,并非提高了效率。而且,有时候把一个foreach语句写成一大坨LINQ表达式,其可读性也不好,所以究竟用还是不用,这个就看你的需要了。

二、延迟执行(Deferred Loading)

像上述例子的那种使用yield return的方式返回一个可枚举类型的函数,都会被“延迟”执行,要证明这点很简单,改一下上面的代码:

        static IEnumerable<int> FindGreaterThan5(IEnumerable<int> list)
{
foreach (var i in list)
{
if (i >= )
yield return i;
else
{
throw new Exception("你看不到这个异常");
}
}
} static void Main(string[] args)
{
List<int> listTest = new List<int>{ , , , , , , , }; //找出所有大于等于5的数
IEnumerable<int> result = FindGreaterThan5(listTest);
}

这个程序执行没有任何问题,你看不到异常,因为FindGreaterThan5根本没有被执行,它只有在返回结果被用到的时候才会真正去执行(这样做的好处后面会提到)。如果你把foreach加上,改为:

        static void Main(string[] args)
{
List<int> listTest = new List<int>{ , , , , , , , }; //找出所有大于等于5的数
IEnumerable<int> result = FindGreaterThan5(listTest);
foreach (var i in result)
{
Console.WriteLine(i);
}
}

那这个异常就会出现,这个地方是要十分小心的,假如你这么写:

            IEnumerable<int> result;
try
{
result = FindGreaterThan5(listTest);
}
catch(Exception) //你捕捉不到异常的
{
return;
}

那是捕捉不到异常的,因为它实际上发生的地方是接下来的foreach处。解决方法有两种,一是try foreach语句,另一是“再包一层”,创建一个“Roll”函数:

        static IEnumerable<int> FindGreaterThan5Roll(IEnumerable<int> list)
{
return FindGreaterThan5(list);
}

然后try这个函数。

三、什么是LINQ to SQL?

貌似讲了一堆跟LINQ to SQL无关的东西,但我向你保证理解这些内容真的很重要!OK……终于到了其它一般的教程的那个开头:什么是LINQ to SQL?

跟LINQ to Object一样,LINQ to SQL能够使得你对Microsoft SQL Server的访问代码变得简洁,它是对ADO.net的封装。所以它并非ADO.net的替代品,也不能带来执行效率上的提高(用的不好反而会更低 效)。这里还需要特别说明的是:

  1. 只能用于Microsoft SQL Server这套DBMS,2005版及2008版我都试过,没问题。Oracle?MySQL?没门;
  2. LINQ to SQL已经有了更强大和复杂的替代品,LINQ to Entity Framework,简称LINQ to EF或者Entity Framework,详情请自行Google一下。

那为什么还用LINQ to SQL?一来它继续长期有效(虽然微软停止更新它了),二来够用并且好用,而LINQ to EF则相对复杂。

使用LINQ to SQL其实仍然是使用ADO.net,只是LINQ to SQL帮助你生成各个查询语句,不需要你手工来写,这样有什么好处?最大的好处就是:只要你的代码编译通过,那么就能生成正确的SQL语句,而不是报运行时错误,然后让你去检查SQL语句。

当然,好处不止这个,还有如:简单,开发快捷,更灵活的where从句生成等。

四,看看LINQ to SQL到底干了些啥?——创建自己的工具类

前面说了,LINQ to SQL其实是“聪明”地帮你生成查询语句,但你不能完全相信它,因为它有时候是“自作聪明”,所以你要在调试的时候看看它究竟干了些什么。我的方法是将它 的生成的SQL语句打印到Debug窗口中,这个小技巧帮我找到了不少的问题,OK,这里我把我写的这个小小的DataContext的帮助类贴出来:

    public class DebugWriter : TextWriter
{
public override void WriteLine(string value)
{
Debug.WriteLine(value);
} public override void WriteLine(string format, params object[] arg)
{
Debug.WriteLine(format, arg);
} public override Encoding Encoding
{
get { return Encoding.UTF8; }
}
} public static class DataContextHelper
{
public static void InitForModification(this DataContext dc)
{
dc.DeferredLoadingEnabled = false;
#if DEBUG
dc.Log = new DebugWriter();
#endif
} /// <summary>
/// 如果一个表中的某一列引用到别的表,默认情况下LINQ to SQL会在遍历搜索结果的时候
/// 动态地去获取别的表的内容,这样就可能产生大量的SQL查询
/// 当把DeferredLoadingEnabled设置为false之后,LINQ to SQL则关闭这项功能,省去了大量的开销
/// 事实上,我们更多的时候会用到LoadWith,直接生成一条联表查询
/// </summary>
public static void InitForQuery(this DataContext dc)
{
dc.ObjectTrackingEnabled = false;
dc.DeferredLoadingEnabled = false;
#if DEBUG
dc.Log = new DebugWriter();
#endif
} public static DateTime GetDbDateTime(this DataContext dc)
{
try
{
return dc.ExecuteQuery<DateTime>("SELECT GETDATE()").Single();
}
catch (Exception ex)
{
throw new Exception("Database error.", ex); //建议替换成你的自定义异常类型
}
}
}

如果你对C#的扩展方法语法不是很清楚,那么可以参考我的另一篇博文:http://www.cnblogs.com/guogangj/archive/2012/03/02/2376927.html

这个帮助类很有用,把它引入到你的工程的namespace去吧(在我的工程中,我把它放入一个公共类库中,因为好几个工程都要引用到,避免重复,DRY,OK?)

  • InitForQuery - 用于查询(注意看看我写的那几行注释,后面会提到)
  • InitForModification - 用于增删改
  • GetDbDateTime - 由于LINQ to SQL不直接支持GetDate函数,所以写一个函数来获取DBMS的时间

接下来我们还是用Northwind数据库为例子,看看如何使用LINQ to SQL。(Northwind是一个小型数据库例子,很多代码都用它作为范例,在这里获取它的创建脚本:http://northwinddatabase.codeplex.com/)

五、创建一个基本查询

给你的工程add一个new item,叫Products.dbml,然后打开之,再如图把Products和Categories两张表拽进去。

然后:

        static void Main(string[] args)
{
ProductsDataContext db = new ProductsDataContext();
db.Log = new DebugWriter();
var products = from p in db.Products select p;
foreach (var product in products)
{
Console.WriteLine(product.ProductName+ " (" + product.Category.CategoryName + ")");
}
}

这里也许你有个问题,为什么from写在前面,而不是select,select写在前面不是更符合SQL的习惯么?想想看,如果你能自己在5分钟 内想出来说明你比我聪明(^_^),OK,其实也跟技术本身关系不大,这样做的原因完全是为了我们的开发环境的智能提示(intellisense),知 道from什么了,后面也就有智能提示了,否则select什么?不知道。

F5,调试运行,看吧,这么一点点代码,就能把所有商品名称及其类型都给打印出来了,是不是很方便?——且慢!打开你的Debug窗口看看:

我的天啊,一个查询就能完成的事情,为什么生成了这么多的SQL语句?这就是我前面所提到的DeferredLoadingEnabled这个选 项,看我写的那个帮助类的InitForQuery方法的注释。避免这种情况的方法是关闭这个选项,并显式告诉LINQ to SQL,你需要哪些关联的加载内容,让LINQ to SQL自动给你生成一个联表查询。我们来改进下:

        static void Main(string[] args)
{
ProductsDataContext db = new ProductsDataContext();
db.InitForQuery(); DataLoadOptions ds = new DataLoadOptions();
ds.LoadWith<Product>(p => p.Category);
db.LoadOptions = ds; var products = from p in db.Products select p;
foreach (var product in products)
{
Console.WriteLine(product.ProductName+ " (" + product.Category.CategoryName + ")");
}
}

注意看,这次用了我前面提供的扩展方法InitForQuery,还有一个DataloadOptions选项,告诉LINQ to SQL需要哪些额外信息,这里我们需要Category信息。好,看看Debug窗口,这次只有一个SQL语句:

SELECT [t0].[ProductID], [t0].[ProductName], [t0].[SupplierID], [t0].[CategoryID], [t0].[QuantityPerUnit], [t0].[UnitPrice], [t0].[UnitsInStock], [t0].[UnitsOnOrder], [t0].[ReorderLevel], [t0].[Discontinued], [t2].[test], [t2].[CategoryID] AS [CategoryID2], [t2].[CategoryName], [t2].[Description], [t2].[Picture]
FROM [dbo].[Products] AS [t0]
LEFT OUTER JOIN (
SELECT 1 AS [test], [t1].[CategoryID], [t1].[CategoryName], [t1].[Description], [t1].[Picture]
FROM [dbo].[Categories] AS [t1]
) AS [t2] ON [t2].[CategoryID] = [t0].[CategoryID]

LINQ to SQL聪明地为我们生成了一个left outer join,这正是我们想要的。

这个例子说明了:

  1. 我们在调试的时候得关注下LINQ to SQL到底干了些什么
  2. 使用LoadWith,而不要使用自动延迟加载

另外,如果你不需要Product的所有列的话,你可以这样写:

        var products = from p in db.Products
select new
{
ProductId = p.CategoryID,
ProductName = p.ProductName,
UnitPrice = p.UnitPrice
};

这样生成的SQL语句是不太一样的,自己观察下,但这样生成出来的对象,是不能用于Insert和Update的,这个要注意一下。

六,大致扫一扫

写一篇无微不至的教程并非本文目的,这个已经有了不少好的教程,所以接下来就稍微简略一些,希望能对大家起到一定的抛砖引玉的作用。

1,WHERE

把1994年后雇佣的,或者Title中包含“经理”的员工选出来

            var result =
from e in db.Employees
where e.HireDate >= new DateTime(, , ) || e.Title.Contains("Manager")
select e;

2,DISTINCT

获取有交易的客户ID(重复的去掉)

var result = (from o in db.Orders select new { CustomerID = o.CustomerID }).Distinct();

3,AVG/COUNT/SUM/MIN/MAX

取得产品价格的平均值

            var result = db.Products.Select(p => p.UnitPrice).Average();
var result = db.Products.Average(p => p.UnitPrice);
var result = (from p in db.Products select p.UnitPrice).Average();

从这也能看出写法并不是唯一的。其它集合操作函数也是类似的。

4,GROUP BY

选出每一类的最贵产品、最便宜产品及产品均价

            var result =
from p in db.Products
group p by p.CategoryID into g
select new
{
g.Key,
Amount = g.Count(),
MaxPrice = g.Max(item => item.UnitPrice),
MinPrice = g.Min(item=>item.UnitPrice),
AveragePrice = g.Average(item=>item.UnitPrice)
};

5,CASE WHEN

            var q = from c in db.Customers
select new
{
Name = c.ContactName,
Address = new
{
City = c.City,
Region = c.Region == null ? "Unknown" : c.Region
}
};

翻译为:

SELECT [t0].[ContactName] AS [Name], [t0].[City],
(CASE
WHEN [t0].[Region] IS NULL THEN CONVERT(NVarChar(15),@p0)
ELSE [t0].[Region]
END) AS [Region]
FROM [dbo].[Customers] AS [t0]

6,INNER JOIN和OUTER JOIN

想用LINQ to SQL直接写联表查询是很麻烦的,不过这也是唯一一个相比直接用SQL来得更麻烦的地方。

6.1 內连接

            var result = from d in db.Order_Details
join o in db.Orders on d.OrderID equals o.OrderID
select new {d.OrderID, d.ProductID, d.UnitPrice, o.RequiredDate};

翻译为

SELECT [t0].[OrderID], [t0].[ProductID], [t0].[UnitPrice], [t1].[RequiredDate]
FROM [dbo].[Order Details] AS [t0]
INNER JOIN [dbo].[Orders] AS [t1] ON [t0].[OrderID] = [t1].[OrderID]

另外一种更紧凑的写法

            var result = from d in db.Order_Details
from o in db.Orders.Where(item=>item.OrderID==d.OrderID)
select new { d.OrderID, d.ProductID, d.UnitPrice, o.RequiredDate };

翻译为

        SELECT [t0].[OrderID], [t0].[ProductID], [t0].[UnitPrice], [t1].[RequiredDate]
FROM [dbo].[Order Details] AS [t0], [dbo].[Orders] AS [t1]
WHERE [t1].[OrderID] = [t0].[OrderID]

执行效果一样的

6.2 外连接

             var result = from d in db.Order_Details
join o in db.Orders on d.OrderID equals o.OrderID into temp
from p in temp.DefaultIfEmpty()
select new {d.OrderID, d.ProductID, d.UnitPrice, p.RequiredDate};

另一种更紧凑的写法是:

            var result = from d in db.Order_Details
from o in db.Orders.Where(item => item.OrderID == d.OrderID).DefaultIfEmpty()
select new {d.OrderID, d.ProductID, d.UnitPrice, o.RequiredDate };

翻译为

SELECT [t0].[OrderID], [t0].[ProductID], [t0].[UnitPrice], [t1].[RequiredDate] AS [RequiredDate]
FROM [dbo].[Order Details] AS [t0]
LEFT OUTER JOIN [dbo].[Orders] AS [t1] ON [t1].[OrderID] = [t0].[OrderID]

7,ORDER BY

正序的情况

    var result = from p in db.Products orderby p.UnitPrice select p;

逆序的情况

    var result = from p in db.Products orderby p.UnitPrice descending select p;

也可以选择多列排序

    var result = from p in db.Products orderby p.UnitPrice, p.UnitsInStock select p;

上面的句子也可以这么写,一样的

    var result = from p in db.Products.OrderBy(item => item.UnitPrice).ThenBy(item => item.UnitsInStock) select p;

8,EXISTS

选出没有订单的客户

    var result = from c in db.Customers where !c.Orders.Any() select c;

其实Any还可以带条件参数哦。

9,WHERE IN

查看指定的几个客户的订单

var result = (
from o in db.Orders
where (
new string[] { "AROUT", "BOLID", "FISSA" })
.Contains(o.CustomerID);

10,UNION ALL/UNION

Concat不会去除重复项目,相当于SQL的Union All;而Union会去除重复项,相当于SQL的Union

看看有来自哪些国家的客户和雇员

            var q = (
from c in db.Customers
select c.Country
).Union(
from e in db.Employees
select e.Country
);

11,Intersect/Except (是用复合查询加EXIST实现的)

            var q = (
from c in db.Customers
select c.Country
).Intersect(
from e in db.Employees
select e.Country
);

查询顾客和职员同在的国家,Interset其实是用一个复合查询实现的。

            var q = (
from c in db.Customers
select c.Country
).Except(
from e in db.Employees
select e.Country
);

去除顾客和职员同在的国家。

12,Skip-Take(是用ROW_NUMBER()函数实现的)

获取从第21个产品开始的10个产品。

            var q = (
from p in db.Products
select p
).Skip().Take();

13,直接执行SQL语句查询

如果发现查询语句很难写,(或者写出来LINQ会傻乎乎地生成低效的多次执行)可以考虑直接使用SQL语句,但缺点就是失去了编译器检查的功能,并且得自己构建好一个类,用于存放数据(如果此类还没有的话)。

IEnumerable<Employee> emps = db.ExecuteQuery<Employee>("select * from Employees");

PS:直接写“*”可不太好

14,INSERT

注意:如果指定的ID存在,则会自动执行Update,而不是Insert(LINQ to SQL是不是很“智能”?都有些自作聪明了)

Region nwRegion = new Region()
{
RegionID = ,
RegionDescription = "Rainy"
};
db.Regions.InsertOnSubmit(nwRegion);
db.SubmitChanges();

15,UPDATE

真奇怪,update和insert居然不同,没有一个专门的Update方法,而是直接取出数据库的条目,然后修改其属性,在SubmitChanges,当然,条目的类型必须是dbml自动帮我们生成的类型,不能是自定义的。这是简单的Update的例子:

Customer cust = db.Customers.First(c => c.CustomerID == "ALFKI");
cust.ContactTitle = "Vice President";
db.SubmitChanges();

这是Update多条的例子:

var q = from p in db.Products
where p.CategoryID ==
select p;
foreach (var p in q)
{
p.UnitPrice += 1.00M;
}
db.SubmitChanges();

16,DELETE

先选后删

OrderDetail orderDetail =
db.OrderDetails.First
(c => c.OrderID == && c.ProductID == );
db.OrderDetails.DeleteOnSubmit(orderDetail);
db.SubmitChanges();

17,First/FirstOrDefault/Single(是用TOP实现的)

都是取出一条记录,区别是:

  • First – 至少有一条,否则抛异常
  • FirstOrDefault – 如果一条都没有,则返回默认值(对象的话默认值就是null)
  • Single – 有且只有一条,否则抛异常

选出ID为1的雇员:

Employee theveryemp = db.Employees.Single(item => item.EmployeeID == );

这个语句会立即执行,如果获取不到或者不止一条,则抛出异常。

18,字符串操作

以下这些LINQ中对字符串操作的部分都会被聪明地转变为相关的SQL语句,而不是使用C#代码来操作。具体会被转换成什么,大家动手试试看。

Location = c.City + ", " + c.Country
p.ProductName.Length <
c.ContactName.Contains("Anders")
c.ContactName.IndexOf(" ")
c.ContactName.StartsWith("Maria")
c.ContactName.EndsWith("Anders")
p.ProductName.Substring();
e.HomePhone.Substring(, ) == ""
e.LastName.ToUpper()
c.CategoryName.ToLower()
e.HomePhone.Substring(, ).Trim()
e.HomePhone.Insert(, ":")
e.HomePhone.Remove()
e.HomePhone.Remove(, )
s.Country.Replace("UK", "United Kingdom")

七、查询条件拼接

客户端在查询的时候往往会附带一些查询条件,例如商品名称模糊查询,日期范围,商品类型范围,当然还有分页等等。我们通常把这些查询条件封装到一个 对象中去,然后让服务器来解释这个对象并拼接SQL查询语句。拼接SQL语句是极其容易出错的事情,而且检查起来还比较费劲,因为SQL语句写起来并不像 C#代码那样可以自动格式化。如今使用LINQ to SQL这些问题就不存在了。

var q = from p in db.Products select p;
if(条件A)
{
    q.Where(p=>p.XXX==A);
}
if(条件B)
{
    q.Where(p=>p.YYY!=B);
}
if(条件C)
{
    q.Where(p=>p.ZZZ.Contains(C));
}
//……

回头想想本文初所提到的延迟执行,到这里你应该知道为什么需要延迟执行了吧,就是为了方便你拼接这些LINQ表达式,如果每个select或者where都执行一次,那可是会带来严重的性能问题的。

八、自动事务处理

也许你发现了,对于增删改,都是在SubmitChanges的时候执行,而且一次SubmitChanges,能改多个表多条记录,那事务在哪 里?其实LINQ to SQL已经自动帮我们封装好事务了,在执行的过程中,一旦有一步失败,操作将会回滚,这个完全不需要我们担心。

九、关于自增的ID字段

按设计惯例,每张表都应该有一个自增的ID字段,对于这个字段,其值总是由数据库自动生成的,所以我们在Insert一行的时候,从来不需要指定其 ID。例如,我们查看ProductID的属性列表,有个叫Auto Generated Value的属性,其值为True,即代表这个字段的值是DBMS自动生成的,你不需要指定。

那么我们插入了一条记录之后,我们想取回这个自动生成的ID的值,怎么办呢?按以前的做法是:

select scope_identity()

现在的做法是在SubmitChanges()之后直接通过插入的对象带出这个自动生成的ID的值:

            Category newCategory = new Category {CategoryName = "Fruit", Description = "Fruits..."};
db.Categories.InsertOnSubmit(newCategory);
db.SubmitChanges();
Console.WriteLine(newCategory.CategoryID);

那现在有这么种情况,我要添加一个订单,同时给这个订单添加若干条明细,怎么办?这个看起来有点难,难在哪里?你要添加明细,你就必须知道主档的 ID,但在SubmitChanges之前,你是拿不到主档的ID的;如果你在Insert了主档之后就Submit,那一旦在Insert明细的时候失 败,你就无法回滚了。

OK,其实这么想的话还是按照旧的思路,LINQ to SQL是一套ORM,我们应该直接指定其对象的关系,而不是去关心ID的值是多少,这是正确的做法:

            Order newOrder = new Order { CustomerID = "ALFKI", ShipAddress = "Shanghai ..." };
Order_Detail newDetail1 = new Order_Detail { Discount = 1.0f, ProductID = , Quantity = , UnitPrice = 9.0M };
Order_Detail newDetail2 = new Order_Detail { Discount = 0.9f, ProductID = , Quantity = , UnitPrice = 5.0M };
newOrder.Order_Details.Add(newDetail1);
newOrder.Order_Details.Add(newDetail2);
db.Orders.InsertOnSubmit(newOrder);
db.SubmitChanges();

十、关于默认值

数据库的表中的很多字段都带有默认值,前面提到的自增ID就是一个例子,但大多字段跟ID不同的是:ID是强制的并且一定是DBMS自动分配的,而 这些带默认值的字段则不一定强制,并且允许由用户传入值。如果把这些带默认值的字段跟自增ID一样,设置其“Auto Generated Value”属性为True的话,我们就没办法设置它的值了,它的值总是由DBMS自动分配,而事实上,我们想要的结果是:当我没有给值的时候使用默认 值,当我有给值的时候,使用我的值。很不幸,LINQ to SQL做不到,我尝试过很多种方法,结果很明确,就是做不到!这也许算是LINQ to SQL的一个缺陷吧。

所以,使用LINQ to SQL的话就把DBMS的默认值忽略掉吧,每次都手工把值传进去好了……

总结

感谢你看完本文,本文肯定不是最全面的对LINQ to SQL的技术文章,但真心是本人实战的总结,如果上面提到的内容你都理解,那LINQ to SQL你也就掌握差不多了……呃,我是说即便你再遇到什么问题,你也肯定有解决的思路了。

LINQ to SQL使用教程的更多相关文章

  1. 步步学LINQ to SQL:使用LINQ检索数据【转】

    [IT168 专稿]该系列教程描述了如何采用手动的方式映射你的对象类到数据表(而不是使用象SqlMetal这样的自动化工具)以便能够支持数据表之间的M:M关系和使用实体类的数据绑定.即使你选择使用了自 ...

  2. 步步学LINQ to SQL:将类映射到数据库表【转】

    [IT168 专稿]该系列教程描述了如何采用手动的方式映射你的对象类到数据表(而不是使用象SqlMetal这样的自动化工具)以便能够支持数据表之间的M:M关系和使用实体类的数据绑定.即使你选择使用了自 ...

  3. Linq To sql入门练习 Lambda表达式基础

    using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; usin ...

  4. LINQ to SQL语句(7)之Exists/In/Any/All/Contains

    适用场景:用于判断集合中元素,进一步缩小范围. Any 说明:用于判断集合中是否有元素满足某一条件:不延迟.(若条件为空,则集合只要不为空就返回True,否则为False).有2种形式,分别为简单形式 ...

  5. 年终巨献 史上最全 ——LINQ to SQL语句

    LINQ to SQL语句(1)之Where 适用场景:实现过滤,查询等功能. 说明:与SQL命令中的Where作用相似,都是起到范围限定也就是过滤作用的,而判断条件就是它后面所接的子句.Where操 ...

  6. LINQ to SQL语句(20)之存储过程

    在我们编写程序中,往往需要一些存储过程,在LINQ to SQL中怎么使用呢?也许比原来的更简单些.下面我们以NORTHWND.MDF数据库中自带的几个存储过程来理解一下. 1.标量返回 在数据库中, ...

  7. LINQ to SQL语句(19)之ADO.NET与LINQ to SQL

    它基于由 ADO.NET 提供程序模型提供的服务.因此,我们可以将 LINQ to SQL 代码与现有的 ADO.Net 应用程序混合在一起,将当前 ADO.NET 解决方案迁移到 LINQ to S ...

  8. LINQ to SQL语句(18)之运算符转换

    运算符转换 1.AsEnumerable:将类型转换为泛型 IEnumerable 使用 AsEnumerable<TSource> 可返回类型化为泛型 IEnumerable 的参数.在 ...

  9. LINQ to SQL语句(17)之对象加载

    对象加载 延迟加载 在查询某对象时,实际上你只查询该对象.不会同时自动获取这个对象.这就是延迟加载. 例如,您可能需要查看客户数据和订单数据.你最初不一定需要检索与每个客户有关的所有订单数据.其优点是 ...

随机推荐

  1. PHP组合模式、策略模式

    一.问题 模拟不同课程有不同的收费方式,并且能灵活改变(新增或删减),如讲座可以固定收费也可改为按时收费,研讨会也是. 二.模式简介及关键点 1.在父类代码中使用条件语句是一种退倒,可以用多态来代替条 ...

  2. Android百度地图开发04之POI检索

    POI检索 POI~~~ Point of Interest,翻译过来就是“兴趣点”.我们在使用地图的时候,搜索周边的ktv,饭店,或者宾馆的时候,输入关键字,然后地图展示给我们很多个点, 这些点就是 ...

  3. android调试工具DDMS

    DDMS工作机制    DDMS全称Dalvik Debug Monitor Service.DDMS为IDE和emultor及真正的android设备架起来了一座桥梁,Android DDMS将捕捉 ...

  4. MyBatis实现SaveOrUpdate

    这篇文章主要讲如何通过xml方式实现SaveOrUpdate,但是仍然建议在Service中实现. 例子 <insert id="saveOrUpdate" > < ...

  5. 用SQLData读写数据库自定义类型

    如何读写自定义类型?SQLData是个很直观的解决办法 在oracle使用手册上找到了很好的资料 点击打开链接 http://docs.oracle.com/cd/B10501_01/java.920 ...

  6. 人脸识别算法准确率最终超过了人类 The Face Recognition Algorithm That Finally Outperforms Humans

    Everybody has had the experience of not recognising someone they know—changes in pose, illumination ...

  7. autodock 结果pdb的生成

    Is there a way to save a protein-ligand complex as a PDB file in AutoDock? I have completed my docki ...

  8. [转]c/c++输入函数

    最全输入函数 c/c++ 一: c=getchar(); 功能:读入一个字符 说明:调用此函数时要求在程序的第一行有预编译命令:#include<stdio>,不过在做c++时 有#inc ...

  9. 7.cadence原理图后续[原创]

    一.网表输出 1.自动编号 输出网表前,不能有问号 -- 效果: ---- -- 效果: 2.DRC检查 输出网表前需要DRC检查 3.网表输出 二.生成BOM表 法1: 法2: --- 点击OK: ...

  10. BZOJ 2754 喵星球上的点名(后缀数组)

    题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=2754 题意:给出n个字典串,m个询问串.输出每个询问串出现在多少个字典串中.最后输出每个 ...