zoukankan      html  css  js  c++  java
  • Dapper2.0.78手册翻译

    Dapper - .Net下的一个简单的ORM框架

    特性

    Dapper是一个NuGet库,你可以把它添加到你的项目中,扩展你的IDbConnection接口。

    提供了3个方法

    查询并映射一个实例集合

    public static IEnumerable<T> Query<T>(this IDbConnection cnn, string sql, object param = null, SqlTransaction transaction = null, bool buffered = true)
    

     使用例子

    public class Dog
    {
        public int? Age { get; set; }
        public Guid Id { get; set; }
        public string Name { get; set; }
        public float? Weight { get; set; }
    
        public int IgnoredProperty { get { return 1; } }
    }
    
    var guid = Guid.NewGuid();
    var dog = connection.Query<Dog>("select Age = @Age, Id = @Id", new { Age = (int?)null, Id = guid });
    
    Assert.Equal(1,dog.Count());
    Assert.Null(dog.First().Age);
    Assert.Equal(guid, dog.First().Id);
    

     查询并映射成dynamic集合

    public static IEnumerable<dynamic> Query (this IDbConnection cnn, string sql, object param = null, SqlTransaction transaction = null, bool buffered = true)
    

     使用例子

    var rows = connection.Query("select 1 A, 2 B union all select 3, 4").AsList();
    
    Assert.Equal(1, (int)rows[0].A);
    Assert.Equal(2, (int)rows[0].B);
    Assert.Equal(3, (int)rows[1].A);
    Assert.Equal(4, (int)rows[1].B);
    

     执行无返回结果的sql语句

    public static int Execute(this IDbConnection cnn, string sql, object param = null, SqlTransaction transaction = null)
    

     使用例子

    var count = connection.Execute(@"
      set nocount on
      create table #t(i int)
      set nocount off
      insert #t
      select @a a union all select @b
      set nocount on
      drop table #t", new {a=1, b=2 });
    Assert.Equal(2, count);
    

     插入多个实例对象

    var count = connection.Execute(@"insert MyTable(colA, colB) values (@a, @b)",
        new[] { new { a=1, b=1 }, new { a=2, b=2 }, new { a=3, b=3 } }
      );
    Assert.Equal(3, count); // 3 rows inserted: "1,1", "2,2" and "3,3"
    

    带参数查询

    参数为一个匿名类

    new {A = 1, B = "b"} // A will be mapped to the param @A, B to the param @B
    

     Dapper允许你传入IEnumerable<int>,并将自动参数化你的查询。

    connection.Query<int>("select * from (select 1 as Id union all select 2 union all select 3) as X where Id in @Ids", new { Ids = new int[] { 1, 2, 3 } });
    相当于执行 select * from (select 1 as Id union all select 2 union all select 3) as X where Id in (@Ids1, @Ids2, @Ids3)" // @Ids1 = 1 , @Ids2 = 2 , @Ids2 = 3

    类型转换

    Dapper 支持bool和numeric的自动转换

    connection.Query("select * from User where UserTypeId = {=Admin}", new { UserTypeId.Admin });
    

    多实例映射

    class Post
    {
        public int Id { get; set; }
        public string Title { get; set; }
        public string Content { get; set; }
        public User Owner { get; set; }
    }
    
    class User
    {
        public int Id { get; set; }
        public string Name { get; set; }
    }
    var sql =
    @"select * from #Posts p
    left join #Users u on u.Id = p.OwnerId
    Order by p.Id";
    
    var data = connection.Query<Post, User, Post>(sql, (post, user) => { post.Owner = user; return post;});
    var post = data.First();
    
    Assert.Equal("Sams Post1", post.Content);
    Assert.Equal(1, post.Id);
    Assert.Equal("Sam", post.Owner.Name);
    Assert.Equal(99, post.Owner.Id);

    假设做一个连接查询,将User对象放入Post对象更有意义。将user对象放入Post对象写法

     (post, user) => { post.Owner = user; return post; }

    Dapper可以通过假设Id列的名称为Id或Id来分割返回的行。如果主键不同,或者希望在Id以外的点分割行,可以使用可选的splitOn参数。

    多结果查询

    var sql =
    @"
    select * from Customers where CustomerId = @id
    select * from Orders where CustomerId = @id
    select * from Returns where CustomerId = @id";
    
    using (var multi = connection.QueryMultiple(sql, new {id=selectedId}))
    {
       var customer = multi.Read<Customer>().Single();
       var orders = multi.Read<Order>().ToList();
       var returns = multi.Read<Return>().ToList();
    }
    

     存储过程

    一般写法

    var user = cnn.Query<User>("spGetUser", new {Id = 1},
            commandType: CommandType.StoredProcedure).SingleOrDefault();
    

    第二种写法

    var p = new DynamicParameters();
    p.Add("@a", 11);
    p.Add("@b", dbType: DbType.Int32, direction: ParameterDirection.Output);
    p.Add("@c", dbType: DbType.Int32, direction: ParameterDirection.ReturnValue);
    
    cnn.Execute("spMagicProc", p, commandType: CommandType.StoredProcedure);
    
    int b = p.Get<int>("@b");
    int c = p.Get<int>("@c");
    

     Ansi 字符串和varchar字符串

    Dapper支持varchar参数,如果你在varchar列上使用一个参数执行where子句,请确保以这样的方式传递它:

    Query<Thing>("select * from Thing where Name = @Name", new {Name = new DbString { Value = "abcde", IsFixedLength = true, Length = 10, IsAnsi = true });
    

     在SQL Server上,查询unicode时使用unicode,查询非unicode时使用ANSI是至关重要的。

    每行数据的类型切换

    通常,您希望将给定表中的所有行视为相同的数据类型。但是,在某些情况下,能够将不同的行解析为不同的数据类型是很有用的。这是IDataReader的位置。GetRowParser可以派上用场。

    假设您有一个名为“Shapes”的数据库表,列为:Id、Type和Data,您希望根据Type列的值将其行解析为CircleSquareTriangle对象。

    var shapes = new List<IShape>();
    using (var reader = connection.ExecuteReader("select * from Shapes"))
    {
        // Generate a row parser for each type you expect.
        // The generic type <IShape> is what the parser will return.
        // The argument (typeof(*)) is the concrete type to parse.
        var circleParser = reader.GetRowParser<IShape>(typeof(Circle));
        var squareParser = reader.GetRowParser<IShape>(typeof(Square));
        var triangleParser = reader.GetRowParser<IShape>(typeof(Triangle));
    
        var typeColumnIndex = reader.GetOrdinal("Type");
    
        while (reader.Read())
        {
            IShape shape;
            var type = (ShapeType)reader.GetInt32(typeColumnIndex);
            switch (type)
            {
                case ShapeType.Circle:
                	shape = circleParser(reader);
                	break;
                case ShapeType.Square:
                	shape = squareParser(reader);
                	break;
                case ShapeType.Triangle:
                	shape = triangleParser(reader);
                	break;
                default:
                	throw new NotImplementedException();
            }
    
          	shapes.Add(shape);
        }
    }
    

     MySql中使用自定义变量

    为 了在MySql中使用不带参数的sql,必须在连接字符串中使用Allow User Variables=True

    限制与警告

    Dapper会缓存运行查询结果,这允许它快速实体化对象和快速处理参数。当前实现将此信息缓存到ConcurrentDictionary对象中。只使用过一次的语句将定期从该缓存中刷新。但是,如果您在不使用参数的情况下动态生成SQL语句,则可能会遇到内存问题。

    Dapper不包含数据库实现细节,它依赖于包括SQLite, SQL CE, Firebird, Oracle, MySQL, PostgreSQL和SQL Server的ADO.NET Provider。

    Dapper只是简单的ORM框架,解决95%的应用问题,不试图解决所有问题

    Dapper.Contrib -  dapper的扩展

    特性

    Dapper.Contrib 包含插入、获取、更新和删除记录的方法。

    以下是Dapper.Contrib包含的全部扩展方法清单:

    T Get<T>(id);
    IEnumerable<T> GetAll<T>();
    int Insert<T>(T obj);
    int Insert<T>(Enumerable<T> list);
    bool Update<T>(T obj);
    bool Update<T>(Enumerable<T> list);
    bool Delete<T>(T obj);
    bool Delete<T>(Enumerable<T> list);
    bool DeleteAll<T>();
    

    如果实体模型存在Id属性,Dapper会默认Id属性为主键。

    public class Car
    {
        public int Id { get; set; } // Works by convention
        public string Name { get; set; }
    }
    

    如果实体模型不遵循包含Id属性,则必须在主键属性上加一个[Key] 或者 [ExplicitKey]特性。

    public class User
    {
        [Key]
        int TheId { get; set; }
        string Name { get; set; }
        int Age { get; set; }
    }
    

     [Key] 使用的时候,该属性必须是数据库主键并是自增。

    [ExplicitKey] 只是在代码中作为主键,使用场景是数据库里面不是自增字段,在代码模型中作为主键使用。

    Get 方法

    根据Id获取实体数据

    var car = connection.Get<Car>(1);
    

    获取表中所有的实体数据

    var cars = connection.GetAll<Car>();
    

     Insert 方法

    插入一个实体

    connection.Insert(new Car { Name = "Volvo" });
    

    插入多个实体

    connection.Insert(cars);
    

     Update 方法

    更新一个实体

    connection.Update(new Car() { Id = 1, Name = "Saab" });
    

    更新多个实体

    connection.Update(cars);
    

     Delete 方法

    根据Id删除实体

    connection.Delete(new Car() { Id = 1 });
    

    删除多个实体

    connection.Delete(cars);
    

    删除全部实体

    connection.DeleteAll<Car>();
    

     其他特性

    Dapper.Contrib 中的其他Atribute:

    [Table("Tablename")] - 当表名和实体类名不一样,可使用该Atribute知名数据库中的表名

    [Table ("emps")]
    public class Employee
    {
        public int Id { get; set; }
        public string Name { get; set; }
    }
    

     [Key] - 当数据库中没有自增Id的时候,使用Key这个Atribute来指明自增和主键字段

    public class Employee
    {
        [Key]
        public int EmployeeId { get; set; }
        public string Name { get; set; }
    }
    

     [ExplicitKey] - 当数据库中没有自增字段,使用该Atribute来指明主键字段

    public class Employee
    {
        [ExplicitKey]
        public Guid EmployeeId { get; set; }
        public string Name { get; set; }
    }
    
    • [Write(true/false)] - 该Atribute来指明是否写数据库true为写,false为不写

    • [Computed] - 这个Atribute来指明不用更新数据库的字段

      限制与警告

    • SQLite

    • SQLiteConnection公开了一个与Dapper.Contrib提供的更新扩展冲突的更新事件。有两种方法可以解决这个问题。
    • 1、从SqlMapperExtensions显式调用Update方法
    • SqlMapperExtensions.Update(_conn, new Employee { Id = 1, Name = "Mercedes" });
      

      2、使用一个类型参数来保证方法签名的唯一

    • connection.Update<Car>(new Car() { Id = 1, Name = "Maruti" });
      
  • 相关阅读:
    抓包工具—Fiddler
    vue 统一注册公共组件
    vscode 配置 eslint 自动格式化
    vue axios http 请求 响应拦截
    vue实现菜单权限控制
    webpack之深入浅出externals
    webpack之前端性能优化(史上最全,不断更新中。。。)
    webpack插件url-loader使用规范
    移动端布局最佳实践(viewport+rem)
    本地更新代码同步至github仓库
  • 原文地址:https://www.cnblogs.com/CelonY/p/14220203.html
Copyright © 2011-2022 走看看