Linq to sql与EF零碎知识点总结

------------------------------第一天(2013-3-25)

1.ado.net实体模型,(Ef)

2.创建上下文对象;

调用相应方法,最后调用。savechanges();方法即可;

3.ef:entityframework;

性能不是很差,实质是生成sql脚本;在sqlserver层面上性能损耗不受影响,只是在自动化方面耗点cpu;

4,根据实体的变化,在根据edmx里面的orm的映射关系生成sql,相对整个系统性能,忽略不计;

5.linq和lambda都一样;爱使用哪种就使用哪种;因为编译后的二进制代码是一样定的;

IQueryable<User> col = dinnerDal.User.Where<User>(u => u.Id > 0);lambda表达式;

iqueryable<User> col=from u in dinnerDal.user

                     where u.id>0

                     select u;

6.查询部分列:select new {u.id,u.name}{ado.net entity framework}

7.sql优化:我们只读取需要的数据;

8.func:是一个委托,传入某个参,传出某个参数;

9.编程中包含:命令式编程(ruby);函数式编程(lambda);

10:用到的时候才会去解析表达式执行sql语句;这是linq的一个大的特点;(只要用到它,就去查询,当第二次用到时依然去查询;)

11.iqueryalbe是离线形的集合,查询的数据并没有放到本地上,每次用都得做查询;

12.内存形集合比如list,array;

---------------------------------第二天(2013-3-26)

ef中上下文若new 多个之后若修改一个savechanges后则其他不更新;(相当于不可重复读;数据被改变,但其他上下文数据不会变,更新时,就全乱了;)

所以改正方法:

  1.单例模式;占用内存会疯长,因为每次查询都会跟踪状态;需要保存且不会被gc回收;

什么是延迟加载

  2.使用线程内唯一方法;(每次请求一个新的实例)

 

3.using system.runtime.remoting.message;中(数据槽)

callcontext.setdata("",object);

callcontext.getdata("",object);线程不占用资源,但占用appdomain;callcontext是线程内部的一个内存空间;(线程独享数据)

通过它,创造一个ef的实例向外提供;

EF:可以跨数据库支持多种数据库;

-------linq to sql

----------------------基础

 EFEntities ef = new EFEntities();

            //查询

            //User集 user = ef.User集.Where<User集>(u => u.ID == 1).First<User集>();

            //MessageBox.Show(user.Name);

            //添加

            //ef.User集.Add(new User集 {RoleID=2, Name="郭泽峰", Age=3});

            //修改

            //User集 user = ef.User集.Where<User集>(u => u.ID == 2).FirstOrDefault<User集>();

            //if (user != null)

            //{

            //    user.Name = "哈哈哈hhh";

            //}

            //ef.SaveChanges();

            //User集 users = ef.User集.Where<User集>(u => u.ID == 2).FirstOrDefault<User集>();

            //if (users != null)

            //{

            //    MessageBox.Show(users.Name);

            //}

            //else

            //{

            //    MessageBox.Show("wu");

            //}

            //删除

            ef.User集.Remove(ef.User集.Where<User集>(u => u.ID == 2).FirstOrDefault<User集>());

            ef.SaveChanges();

-------------------------------------------------------------------------可以from嵌套和调用本地方法;

 private void button1_Click(object sender, EventArgs e)

        {

            URDataContext uc = new URDataContext();

            var users = from u in uc.User集

                        select new {Name=cona(u.Name)};

            this.dataGridView1.DataSource = users;

        }

        private string cona(string s)

        {

            return s += "zhuanhuan";

        }

--------------------------------

from c in db.Customers

select c.City )

.Distinct();

--------------------------------记住这两种形式;

var q = db.Products.Select(p => p.UnitPrice).Min();

2.映射形式:

查找任意订单的最低运费:

var q = db.Orders.Min(o => o.Freight);

------------------------聚合函数;

var categories =

from p in db.Products

group p by p.CategoryID into g

select new {

CategoryID = g.Key,

CheapestProducts  =

from p2 in g

where p2.UnitPrice == g.Min(p3 => p3.UnitPrice)

select p2

};

--------------------一对多查询

var q =

from c in db.Customers

from o in c.Orders

where c.City == "London"

select o;

----------------------------做量表关联:ordderss存储的仅仅是orders的集合;(显示所有用户,订单字段只显示有的)相当左链接

   var users = from u in uc.User集

                        join o in uc.Orders

                        on u.ID equals o.Uid into orderss

                        select new {u.Name,cc=orderss.FirstOrDefault().Name};

----相当inner join:或者在from o in orderss后面加上where o.Id!=null;

  var users = from u in uc.User集

                        join o in uc.Orders

                        on u.ID equals o.Uid into orderss

                        from o in orderss

                        select new { u.Name, cc = orderss.FirstOrDefault().Name};

-----------------------------------2.三向联接(There way join):

此示例显式联接三个表并分别从每个表投影出结果:

var q =

from c in db.Customers

join o in  db.Orders on c.CustomerID

equals o.CustomerID into ords

join e in db.Employees  on c.City

equals e.City into emps

select new

{

c.ContactName,

ords = ords.Count(),

emps = emps.Count()

};

------------------------------------左链接表示:(cc:不是一个集合)

       var users = from u in uc.User集

                        join o in uc.Orders

                        on u.ID equals o.Uid into orderss

                        from o in orderss.DefaultIfEmpty()

                        select new {u.Name,cc=o.Name};

-------------------------------------转换添加新的字段(let)

  var users = from u in uc.User集

                        join o in uc.Orders

                        on u.ID equals o.Uid into orderss

                        from o in orderss.DefaultIfEmpty()

                        let z=o.Name+o.Name

                        select new {u.Name,cc=o.Name,z};

-----------------------------------

------------------------------------组合(会出现n*n中组合)

 var users = from u in uc.User集

                        from o in uc.Orders

                        select new {u.Name,cc=o.Name };

 

----------------------

5.组合键(Composite Key):

这个例子显示带有组合  键的联接:

var q =

from o in db.Orders

from p in db.Products

join d in  db.OrderDetails

on new

{

o.OrderID,

p.ProductID

} equals

new

{

d.OrderID,

d.ProductID

}

into details

from d in details

select new

{

o.OrderID,

p.ProductID,

d.UnitPrice

};

说明:使用三个表,并且用匿名类来说明:使用三个表,并  且用匿名类来表示它们之间的

关系。它们之间的关系不能用一个键描述清楚,所  以用匿名类,来表示组合键。还有一种

是两个表之间是用组合键表示关系的,不  需要使用匿名类。

-----------------------------------6.可为 null/不可为 null 的键关系  (Nullable/Nonnullable  Key

Relationship):

这个实例显示如何构造一  侧可为  null  而另一侧不可为  null  的联接:

var q =

from o in db.Orders

join e in db.Employees

on o.EmployeeID equals

(int?)e.EmployeeID into emps

from e in emps

select new

{

o.OrderID,

e.FirstName

};

----------------------------------------排序

   var users = from u in uc.User集

                        orderby u.ID,u.Name

                        select new { u.Name, cc = o.Name };

---------

 var users = uc.User集.OrderBy(u => u.ID).ThenBy(u=>u.Name);

-------

  var users = uc.User集.OrderBy(u => u.ID).OrderBy(u=>u.Name);

这两个都行;

----

 var users = uc.User集.OrderByDescending(u => u.ID).OrderByDescending(u=>u.Name);

----------------

需要  说明的是,OrderBy 操作,不支持按 type 排序,也不支持匿名类。比如

var q =

db.Customers

.OrderBy(c => new

{

c.City,

c.ContactName

}).ToList();

会被抛出异常。错误是前面的操作有匿名类,再  跟 OrderBy 时,比较的是类别。比如

var q =

db.Customers

.Select(c => new

{

c.City,

c.Address

})

.OrderBy(c => c).ToList();

如果你想使用 OrderBy(c  =>  c),其前提条件是  ,前面步骤中,所产生的对象的类别必须为

C#语言的基本类型。比如下句,这里  City 为 string 类型。

----------------------------

--------------------------------------这样也可;

 var users = from u in uc.User集

                        orderby u.ID ascending

                        select u;

---------------------两个字段按相反排序;

var q =

from o in db.Orders

where o.EmployeeID == 1

orderby o.ShipCountry,  o.Freight descending

select o;

----------------------结合groupby;

var q =

from p in db.Products

group p by p.CategoryID into g

orderby g.Key

-----------------------------------------分组(  group u by u.RoleID into g select g;的话结果只显示key字段;)结果是《int,集》形式,所以需要再查一次;

  var users = from u in uc.User集

                        group u by u.RoleID into g

                        from gg in g

                        where g.Key==2

                        select gg;

-------------------------------

var q =

from p in db.Products

group p by  p.CategoryID into g

select new { CategoryID = g.Key, g };实际上达到的效果是将g.key替换成了CategoryID,

foreach (var gp in q)

{

if (gp.CategoryID == 2)

{

foreach (var item in gp.g)

{

//do  something

}

}

}

----------------------

3.最大  值

var q =

from p in db.Products

group p by p.CategoryID into g

select new {

g.Key,

MaxPrice = g.Max(p => p.UnitPrice)

};

----------------------------------------

7.计数

var q =

from p in db.Products

group p by p.CategoryID into g

select new {

g.Key,

NumProducts  = g.Count()

};

---------------------------------------------

10.多列(Multiple Columns)

var categories =

from p in db.Products

group p by new

{

p.CategoryID,

p.SupplierID

}

into g

select new

{

g.Key,

g

};

语句描述:使用 Group By 按 CategoryID 和  SupplierID 将产品分组。

说明:既按产品的分类,又按供应商分类。在  by 后面,new 出来一个匿名类。这里,Key

其实质是一个类的对象, Key 包含两个  Property: CategoryID、 SupplierID。用 g.Key.CategoryID

可以遍历 CategoryID  的值。

--------------------------------------------------

10.多列(Multiple Columns)

var categories =

from p in db.Products

group p by new

{

p.CategoryID,

p.SupplierID

}

into g

select new

{

g.Key,

g

};

语句描述:使用 Group By 按 CategoryID 和  SupplierID 将产品分组。

说明:既按产品的分类,又按供应商分类。在  by 后面,new 出来一个匿名类。这里,Key

其实质是一个类的对象, Key 包含两个  Property: CategoryID、 SupplierID。用 g.Key.CategoryID

-----------------------------------------------------------

 

可以遍历 CategoryID  的值。

----------

var categories =

from p in db.Products

group p by new { Criterion = p.UnitPrice > 10 } into g

select g;

语句描述  :使用 Group  By 返回两个产品序列。第一个序列包含单价大于 10 的产品。第二

个  序列包含单价小于或等于 10 的产品。

-----------------(只要不为空就行)

 var users = from u in uc.Role集

                        where u.User集.Any()

                        select u;

----------

 var users = from u in uc.Role集

                        where u.User集.Any(c=>c.ID<1)

                        select u;

 

等效于

   var users = (from u in uc.Role集

                        from uu in u.User集

                        where uu.ID>0

                        select u).Distinct();

 

-----------------------any的作用实际上是只要子集有一个符合条件即可成立;all(集合中所有都必须满足条件才能返回true;)

--------------contains包含

var q = (

from o in db.Orders

where (

new string[] { "AROUT", "BOLID", "FISSA" })

.Contains (o.CustomerID)

select o).ToList();

Not Contains 则取反:

var q = (

from o in db.Orders

where !(

new string[] { "AROUT",   "BOLID", "FISSA" })

.Contains(o.CustomerID)

select o).ToList();

1.包含一个对象:

1.包含一个对象:

var order = (from o in db.Orders

where o.OrderID == 10248

select o).First();

var q = db.Customers.Where(p  => p.Orders.Contains(order)).ToList(); 

-----

var users = from u in uc.User集

                        where (new string[] { "a", "b" }).Contains(u.Name)

                        select u;

--------------------

2.包含多个值:

string[] cities =

new string[] { "Seattle", "London", "Vancouver", "Paris" };

var q = db.Customers.Where (p=>cities.Contains(p.City)).ToList();

---------------------------查询单个比如u.uname;必须是select new{u.uname};否则显示的是length;切记;----

 

---contact:合并项;

---union:合并并去除相同的项;

---Intersect:去交集;

--except: (from u in uc.User集

                         select new { u.ID }).Except(

                         from u in uc.Role集

                         select new { u.ID }

                         );需要注意: 返回第一个集合中,第二个集合没有的元素。除。。。。之外;

----

 

-----需要添加引用:system.data.linq.sqlclient;

  var users = from u in uc.User集

                        where SqlMethods.Like(u.Name, "%郭%")

                        select u;

-------------------------

比如查询消费者 ID 没有“AXOXT”形式的消费者  :

var q = from c in db.Customers

where ! SqlMethods.Like(c.CustomerID, "A_O_T")

select c;

DateDiffDay

-----------------------------

var q = from o in db.Orders

where SqlMethods

.DateDiffDay (o.OrderDate, o.ShippedDate) < 10

select o;

-----------------------------插入需要注意事项;

2.一对多  关系

说明:Category 与 Product 是一对多的关系,提交 Category(一端)的数据  时,LINQ to SQL 会

自动将 Product(多端)的数据一起提交。

var newCategory = new Category

{

CategoryName = "Widgets",

Description = "Widgets are the  ……"

};

var newProduct = new Product

{

ProductName = "Blue Widget",

UnitPrice = 34.56M,

Category = newCategory

};

db.Categories.InsertOnSubmit(newCategory);

db.SubmitChanges  ();

语句描述:使用 InsertOnSubmit 方法将新类别添加到 Categories  表中,并将新 Product 对象

添加到与此新 Category 有外键关系的 Products 表中。  调用 SubmitChanges 将这些新对象及

其关系保存到数据库。

 

 

-----------------------------多对多时 插入要分别插入;

3.多对多关系

说明:在多对多关系中,我们需要依次提交。

var newEmployee = new Employee

{

FirstName = "Kira",

LastName = "Smith"

};

var newTerritory = new Territory

{

TerritoryID = "12345",

TerritoryDescription = "Anytown",

Region = db.Regions.First()

};

var newEmployeeTerritory = new EmployeeTerritory

{

Employee = newEmployee,

Territory = newTerritory

};

db.Employees.InsertOnSubmit(newEmployee);

db.Territories.InsertOnSubmit(newTerritory);

db.EmployeeTerritories.InsertOnSubmit(newEmployeeTerritory);

db.SubmitChanges();

语句描述:使用 InsertOnSubmit 方法将新雇  员添加到 Employees  表中,将新 Territory 添加

到 Territories 表中,并将新  EmployeeTerritory 对象添加到与此新 Employee 对象和新 Territory

对象有外键关  系的 EmployeeTerritories 表中。调用 SubmitChanges 将这些新对象及其关系保

持  到数据库。

-----------------------

说明  :CUD 就是 Create、Update、Delete 的缩写。下面的例子就是新建一个 ID(主键)  为 32--------------------------弄不明白。若id为主键的话禁止插入重复项;

的 Region,不考虑数据库中有没有 ID 为 32 的数据,如果有则替换原来的数据  ,没有则插

入。

Region nwRegion = new Region()

{

RegionID = 32,

RegionDescription = "Rainy"

};

db.Regions.InsertOnSubmit(nwRegion);

db.SubmitChanges  ();

---------------------------多项修改:

2.多项更改

var q = from p in db.Products

where p.CategoryID == 1

select p;

foreach (var p in q)

{

p.UnitPrice += 1.00M;

}

db.SubmitChanges  ();

--------------插入时,若id自增,相当于id没有赋值1,但不报错,插入后id为最大值+1

  Role集 r = new Role集();

            r.RName = "新添加的";

            r.ID = 1;

---------------------不明白;

3.推理删除(Inferred Delete)

 

 

---------------------

使用 Attach 更新(Update with Attach):::::不明白;

------

并发  两个或更多用户同时尝试更新同一数据库行的情形。

并发冲突  两个或更多用户同时尝试向  一行的一列或多列提交冲突值的情形。

并发控制  用于解决并发冲突的技术。

开放式并发控制  先调查其他事务是否已更改了行中的值,再允许提交更改的技术。相  比之

下,保守式并发控制则是通过锁定记录来避免发生并发冲突。之所以称作开  放式控制,是

因为它将一个事务干扰另一事务视为不太可能发生。

冲突解决  通过重新查询数据库刷新出现冲突的项  ,然后协调差异的过程。刷新对象时, LINQ

to  SQL  更改跟踪器会保留以下数据  :最初从数据库获取并用于更新检查的值  通过后续查

询获得的新数据库值。   LINQ to SQL  随后会确定相应对象是否发生冲突(即它的一个或多个

成员值是否  已发生更改)。如果此对象发生冲突,LINQ to  SQL  下一步会确定它的哪些成员

发生冲突。LINQ to SQL  发现的任何成员冲突都会添加到冲突列表中。

 

-------------------------如何处理并发,不明白;

2.DateTime.Month

var q =

from o in db.Orders

where o.OrderDate.Value.Month  == 12

select o;

-------------------

7.String.Substring(start)

var q =

from p in db.Products

select p.ProductName.Substring(3);

语句描述:这个例子使用 Substring 方  法返回产品名称中从第四个字母开始的部分。

8.String.Substring  (start, length)

var q =

from e in db.Employees

where e.HomePhone.Substring(6,  3) == "555"

select e;

---------------------在索引为1的地方插入12;

 select new {a= u.Name.Insert(1,"12")};

-----

14.String.Remove(start,  length)

a= u.Name.Replace("a","b")

-------------------------------------------------------------

对于对象。你期望在你反复向  DataContext  索取相同的信息时,它实际上会为你提供同一对

象实例。你将它们  设计为层次结构或关系图。你希望像检索实物一样检索它们,而不希望

仅仅因为  你多次索要同一内容而收到大量的复制实例。

在  LINQ to SQL  中,   DataContext  管理对象标识。只要你从数据库中检索新行,该行就会由

其主键记  录到标识表中,并且会创建一个新的对象。只要您检索该行,就会将原始对象实  例

传递回应用程序。通过这种方式, DataContext  将数据库看到的标识(即主键  )的概念转换

成相应语言看到的标识(即实例)的概念。应用程序只看到处于第  一次检索时的状态的对

象。新数据如果不同,则会被丢弃。

LINQ to SQL  使用此方法来管理本地对象的完整性,以支持开放式更新。由于在最初创建对

象  后唯一发生的更改是由应用程序做出的,因此应用程序的意向是很明确的。如果  在中间

阶段外部某一方做了更改,则在调用  SubmitChanges()  时会识别出这些  更改。

-----------------------------

预先加载:LoadWith  方法

你如果想要同时查询出一些对象的集合的  方法。LINQ to SQL  提供了  DataLoadOptions 用于

立即加载对象。方法包括:

LoadWith  方法,用于立即加载与主目标相关的数据。

AssociateWith  方法,用于筛选为特定关系检索到的对象。----------

NorthwindDataContext db = new NorthwindDataContext ();

DataLoadOptions ds = new DataLoadOptions();

ds.LoadWith<Customer>(p  => p.Orders);

db.LoadOptions  = ds;

var custs = (

from c in db2.Customers

where c.City == "Sao Paulo"

select c);----------------------------------这时数据已经查询了;

foreach (var cust in custs)

{

foreach (var ord in cust.Orders)

{

Console.WriteLine  ("CustomerID {0} has an OrderID {1}.",

cust.CustomerID,

ord.OrderID);

}

}

------------------------------------转化成数组.ToArray();

               select u;

            User集[] ss = users.ToArray();

            MessageBox.Show(ss[1].Name);

------------------转化成泛型列表;

var q =

from e in db.Employees

where e.HireDate  >= new DateTime(1994, 1, 1)

select e;

List<Employee> qList = q.ToList(

-------------------------转化成字典;

 Dictionary<int, User集> d = users.ToDictionary(u=>u.ID);

------------------

//新建一个  标准的 ADO.NET 连接:

SqlConnection  nwindConn  = new SqlConnection  (connString);

nwindConn.Open();

// ...  其它的 ADO.NET 数据操作  代码... //

//利用现有的 ADO.NET 连接来创建一个 DataContext:

Northwind interop_db  = new Northwind(nwindConn);

var orders =

from o in interop_db.Orders

where o.Freight > 500.00M

select o;

//返回 Freight>500.00M 的订单

nwindConn.Close();

------------------------------------------将存储过程拖进去直接调用就行了;

--------如果返回时output:必须用ref;

  uc.StoredProcedure4(ref id);

            MessageBox.Show(id.ToString());

 

 

 

原文地址:https://www.cnblogs.com/guozefeng/p/3209316.html