Dapper2.0.78手册翻译

摘要:
Dapper-下的一个简单ORM框架特性。Net Dapper是一个NuGet库。您可以将其添加到项目中并扩展IDbConnection接口。)null,Id=guid});明确肯定相同的明确肯定无效的明确肯定相同的查询并映射到动态集合publicstaticEnumerableQuery。使用示例varrows=连接。查询AsList();明确肯定相同的明确肯定相同的明确肯定相同的明确肯定相同的执行sql语句publicstaticinExecute,但不返回结果。使用varcount=connection示例。处决明确肯定相同的插入多个实例对象varcount=connection。处决明确肯定相等;//3插入:“1,1”,“2,2”和“3,3”带参数的查询参数是一个匿名类new{A=1,B=“B”}//Awillbemappedtotheparam@A , Btotheparam@BDapper允许您传入IEnumerable<int>,并将自动参数化查询。将用户对象放入Post对象写入方法=˃{Post.Owner=user;returnpost;}Dapper可以通过假设Id列的名称为Id或Id来拆分返回的行。
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" });
    

免责声明:文章转载自《Dapper2.0.78手册翻译》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇汇编语言——寄存器(内存访问 ss栈段寄存器)C++中tuple类型下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

oracle group 语句探究(笔记)

1、group by语句在oracle中没有排序功能,必须依靠order by才能实现按照预定结果的排序 2、group by 的cube扩展 1 with test as 2 ( 3 select 1 id,2 name from dual 4 ) 5 select id,name from test group by cube(id,...

SQL优化(Oracle)

(转)SQL优化原则一、问题的提出  在应用系统开发初期。因为开发数据库数据比較少。对于查询SQL语句,复杂视图的的编写等体会不出SQL语句各种写法的性能优劣,可是假设将应用系统提交实际应用后,随着数据库中数据的添加。系统的响应速度就成为眼下系统须要解决的最基本的问题之中的一个。系统优化中一个非常重要的方面就是SQL语句的优化。对于海量数据,劣质SQL...

sql优化(oracle)

系统优化中很重要的方面是SQL语句的优化,对于海量数据,优质的SQL能够有效的提高系统的可用性。 总结的有点罗嗦,列个简单的目录啦~ 目录 第一部分 知识准备                            第二部分 常用sql用法和注意事项                                第三部分  sql优化总结     1.  s...

hive QL 插入语法

1.insert 语法格式为:基本的插入语法:INSERT OVERWRITE TABLE tablename [PARTITON(partcol1=val1,partclo2=val2)]select_statement FROM from_statementinsert overwrite table test_insert select * from...

DB2带UPDATE,INSERT语句的函数

带UPDATE,INSERT 语句的函数返回值应该是一个TABLE如:RETURNS TABLE(COL VARCHAR(36))函数中返回应该:return select NEWID from sysibm.sysdummy1;在调用时例子: select*fromtable(UF_GETID('RE'))ast 创建ID函数: CodeCREAT...

基础sql整理

参考https://www.cnblogs.com/yoyoketang/ student表: grade表: 1.查询所有学生的数学成绩,显示学生姓名name,分数由高到低 SELECT a.name,b.score from sentiment.student a left join sentiment.grade b on a.id = b.id...