zoukankan      html  css  js  c++  java
  • 数据访问层及EntityFramework

    数据访问层(Data Access Layer)负责与数据储存设备打交道,为业务层提供数据服务(一般指增、删、改、查)。一个好的数据访问层可在不影响其他逻辑的情况下,替换数据访问技术、数据据库。

    数据访问层的常见模式与原则

    • 工作单元(Unit of Work)
      维护一系列操作的事务性(Transaction),一系列操作要么都成功,如果有一个操作失败,则事务回滚。这里也主要用于对数据库的操作。
      如果通过sql脚本直接访问数据库,可以直接用sql调用相应数据库的事务。
      如果采用自己写的ORM,则可定义一个IUnitOfWork接口,将增、删、改的数据保存进集合,在Commit方法将object数据存储数据库,可通过TransactionScope实现事务使用方式连接
        public interface IUnitOfWork
        {
            void RegisterAmended(IAggregateRoot entity, IUnitOfWorkRepository unitofWorkRepository);
            void RegisterNew(IAggregateRoot entity, IUnitOfWorkRepository unitofWorkRepository);
            void RegisterRemoved(IAggregateRoot entity, IUnitOfWorkRepository unitofWorkRepository);
            void Commit();
        }
    

    如果利用第三方ORM库,一般都提供Unit of work

    • 标识映射
      标识映射即通过唯一标识,将加载的数据存入缓存,方便下次访问。
    • 延迟加载 表示需要时才去加载所需的资源。一般指需要时采取加载外键关联的表。如在学生管理系统,每个学生都有自己的成绩,在展示学生列表时不加载成绩,只有进入某个学生详细信息才加载。
    • 数据并发控制
      同时修改一份数据造成修改冲突,一般通过为数据添加一个version属性表明版本。

    EntityFramework

    EntityFramework是微软官方提供的ORM类库,其采用Repository模型,功能强大,这里简单介绍下其数据访问层特性的实现。

    工作单元(Unit of Work)

    1. 隐式事务
      using (var context = new MyStoreContext())
      {
        customer = new Customer { FirstName = request.FirstName, LastName = request.LastName };
        context.Customers.Add(customer);
        context.SaveChanges();
        return customer;
      }
    

    其中context.SaveChanges()方法事务执行,其内部实现了事务。
    2. 显示事务

    using (var context = new BloggingContext())
    {
        using (var transaction = context.Database.BeginTransaction())
        {
            try
            {
                context.Blogs.Add(new Blog { Url = "http://blogs.msdn.com/dotnet" });
                context.SaveChanges();
    
                context.Blogs.Add(new Blog { Url = "http://blogs.msdn.com/visualstudio" });
                context.SaveChanges();
    
                var blogs = context.Blogs
                    .OrderBy(b => b.Url)
                    .ToList();
    
                transaction.Commit();
            }
            catch (Exception)
            {
                // TODO: Handle failure
            }
        }
    }
    
    1. Cross-context transaction(跨库的事务)
    using (var context1 = new BloggingContext(connectionstring1))))
    {
        using (var transaction = context1.Database.BeginTransaction())
        {
            try
            {
                context1.Blogs.Add(new Blog { Url = "http://blogs.msdn.com/dotnet" });
                context1.SaveChanges();
    
                using (var context2 = new BloggingContext(connectionstring2))
                {
                    //context2 用context1的事务
                    context2.Database.UseTransaction(transaction.GetDbTransaction());
    
                    var blogs = context2.Blogs
                        .OrderBy(b => b.Url)
                        .ToList();
                }
    
                transaction.Commit();
            }
            catch (Exception)
            {
                // TODO: Handle failure
            }
     
    

    延迟性加载

    EntityFramework 默认为延迟加载,如果希望饥渴加载需要include

    数据并发控制

    为实体添加version属性

       [Timestamp]
        public byte[] RowVersion { get; set; }
    

    通过异常机制查询保存的数据是否被修改或删除,异常为DbUpdateConcurrencyException

  • 相关阅读:
    js中的replace替换全部
    Oracle中创建数据链
    Hbuildx+vue+axios+element ui初学部署
    html5抠图
    Oracle误删除数据的恢复方法
    vs 生成项目自动关闭当前运行程序
    Mvc项目在iis上面显示文件夹 输入地址页面也打不开
    FastReport快速打印(.net)
    脚本之家
    VS自定义作者、创建时间
  • 原文地址:https://www.cnblogs.com/LoveTomato/p/9408868.html
Copyright © 2011-2022 走看看