------------------------------第一天(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());