• 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());

     

     

     

  • 相关阅读:
    《黑马程序员》 内存管理的认识(Objective
    《黑马程序员》 description方法(Objective
    《黑马程序员》 类的加载和初始化(Objective
    《黑马程序员》 category分类的使用(Objective
    《黑马程序员》 OC构造方法(Objective
    《黑马程序员》 OC编译器特性(Objective
    《黑马程序员》 OC的三大特性(Objective
    《黑马程序员》 OC的认识和第一个OC(Objective
    《黑马程序员》 extern与static的使用注意(C语言)
    《黑马程序员》 typedef的使用方法(C语言)
  • 原文地址:https://www.cnblogs.com/guozefeng/p/3209316.html
Copyright © 2020-2023  润新知