NPOCO

来源:互联网 发布:通达信手机炒股软件 编辑:程序博客网 时间:2024/06/17 05:33

转自:http://www.bkjia.com/C_jc/1223444.html


从数据库映射到现在有对象

 

使用 SingleIntoSingleOrDefaultIntoFirstInto 和 FirstOrDefaultInto 方法,可以将数据库的列映射到现有对象。只有查询中的列将被设置在现有对象上。

1 public class User 2 {3     public int UserId { get;set; }4     public string Email { get;set; }5 }6 7 var user = new User() { UserId = 1 };8 IDatabase db = new Database("connStringName");9 db.SingleOrDefaultInto(user, "select Email from users where userid = @0", 1);

 

一对多的查询

 

这帮助您映射一个与嵌套列表对象有一对多关系的查询。鉴于以下类:

 1     public class UserDto 2     { 3         public int UserId { get; set; } 4         public string Name { get; set; } 5         public List<CarDto> Cars { get; set; } 6     } 7  8     public class CarDto 9     {10         public string Make { get; set; }11         public string Color { get; set; }12     }

查询:

1 IDatabase db = new Database("connStringName");2 3 //v24 var users = db.FetchOneToMany<UserDto, CarDto>(x => x.UserId, 5     "select u.*, c.* from Users u inner join Cars c on u.UserId = c.UserId order by u.UserId");6 7 //v38 var users = db.FetchOneToMany<UserDto>(x => x.Cars, 9     "select u.*, c.* from Users u inner join Cars c on u.UserId = c.UserId order by u.UserId");

这将为您提供一个UserDto对象的列表,并且对于每个对象,也将填充CarDto的列表。

注意:

 

对嵌套对象映射

 

这将帮助您将查询映射到有嵌套对象的对象。鉴于以下类:

 1     public class User 2     { 3         public int UserId { get; set; } 4         public string Name { get; set; } 5         public Address Address { get; set; } 6     } 7  8     public class Address 9     {10         public string Street { get; set; }11         public string City { get; set; }12     }

查询:

1 IDatabase db = new Database("connStringName");2 var users = db.Fetch<User, Address>("select u.UserId, u.Name, u.Street, u.City from Users");

这将给您一个使用嵌套类映射的 user 对象列表。

注意:

 

字典和对象数组查询

 

有时,您不知道查询返回的列。这就是能够映射到字典< string,object >,或object[]的地方。字典和对象数组查询。

1 var users = db.Fetch<Dictionary<string, object>>("select * from users");2 3 or4 5 var users = db.Fetch<object[]>("select * from users");

注意:

从NPoco版本 > 1.0.3 开始,所有数组类型(值类型。string[]、int[]、double[]、DateTime[]等)将是一个有效的通用参数。

 

跟踪更改的更新

 

使用快照

快照用于跟踪实体的更改,因此只有更改的属性才会被更新。在下面的示例中,只有新 Name 将被发送到数据库,因为它的年龄值与启动快照时的值相同。

1 IDatabase db = new Database("connString");2 var user = db.SingleById<User>(1);  // Name = "Ted", Age = 213 4 var snapshot = db.StartSnapshot(user);  // 在此之后的任何更改都将被记录。5 6 user.Name = "Bobby";7 user.Age = 21;8 9 db.Update(user, snapshot.UpdatedColumns());  // 只更新Name列

只有在UpdatedColumns()之前的更改将被包含在变更集中。

 

复合主键

 

复合键可以指定通过放置两个逗号之间的列名称 [PrimaryKey] 属性。

1 [TableName("Users")]2 [PrimaryKey("UserId,UserName")]3 public class User4 {5     public int UserId { get; set; }6     public string UserName { get;set; }7 }

当设置了复合键,AutoIncrement属性总是默认false

如果你想使用 SingleById 方法查找一个对象,就可以使用匿名类型。

1 IDatabase db = new Database("connStringName");2 var user = db.SingleById<User>(new {UserId = 1, UserName = "user"});

 

多个结果集

 

该特性使您能够在只调用一次数据库的情况下映射多个查询。

FetchMultiple 方法返回一个  Tuple < T >,List < T1 > >。

1 IDatabase db = new Database("connStringName");2 Tuple<List<User>, List<Address>> data = db.FetchMultiple<User, Address>("select * from users;select * from addresses;");3 var users = data.Item1;4 var addresses = data.Item2;

支持:

这仅支持可以返回多个结果集的数据库。在IDataReader上实现了NextResult()。通过Npgsql支持Sql Server和Postgresql。

 

流利的映射

 

对于一个类的映射,您可以使用 Map < T > 继承,其中 T 是要映射的类。

 1 public class UserMapping : Map<User> 2 { 3     public UserMapping() 4     { 5         PrimaryKey(x => x.UserId); 6         TableName("Users"); 7         Columns(x => 8         { 9             x.Column(y => y.Name).Ignore();10             x.Column(y => y.Age).WithName("a_ge");11         });        12     }13 }

映射也可以从映射继承,并使用For < >方法在一次类中指定所有的映射。

1 public class OurMappings : Mappings2 {3     public OurMappings()4     {5         For<User>().Columns( ....6     }7 }

 

数据库工厂设置:

 

您只需要创建映射一次,我们使用数据库工厂来完成此操作。

1 public void Application_Start()2 {3     MyFactory.Setup();4 }

 

 1 public static class MyFactory 2 { 3     public static DatabaseFactory DbFactory { get; set; } 4  5     public static void Setup() 6     { 7         var fluentConfig = FluentMappingConfiguration.Configure(new OurMappings()); 8         //或单个的映射  9         //var fluentConfig = FluentMappingConfiguration.Configure(new UserMapping(), ....);10 11         DbFactory = DatabaseFactory.Config(x =>12         {13             x.UsingDatabase(() => new Database("connString"));14             x.WithFluentConfig(fluentConfig);15             x.WithMapper(new Mapper());16         });17     }18 }

然后你可以在你的代码中使用它。

1 var database = MyFactory.DbFactory.GetDatabase();

如果你使用的是容器,那么你可以使用类似的东西

1 For<IDatabase>().Use(() => MyFactory.DbFactory.GetDatabase());

 

简单LINQ查询

 

Query<T>

NPoco介绍了一种使用LINQ查询获取对象的简单方法。这里有一个简单的例子。

1 IDatabase db = new Database("connString");2 db.Query<User>().Where(x => x.Name == "Bob")3                            .OrderBy(x => x.UserId)4                            .Limit(10, 10)5                            .ToList();

可用的LINQ关键字:

  • ProjectTo
  • Count
  • Any
  • Where
  • OrderBy
  • OrderByDescending
  • ThenBy
  • ThenByDescending
  • Limit
  • Include
  • IncludeMany

这里是你如何使用一个IN子句:

1 var users = db.Query<User>().Where(x => new[] {1,2,3,4}.Contains(x.UserId)).ToList();2 // 或者使用 'In' 扩展方法3 var users = db.Query<User>().Where(x => x.UserId.In(new[] {1,2,3,4})).ToList();

在where子句中也可以使用许多字符串方法。这里有几个例子:

1 var users = db.Query<User>().Where(x => x.Name.StartsWith("Bo")).ToList();2 var users = db.Query<User>().Where(x => x.Name.EndsWith("ob")).ToList();3 var users = db.Query<User>().Where(x => x.Name.Contains("o")).ToList();4 var users = db.Query<User>().Where(x => x.Name.ToLower() == "bob").ToList();5 var users = db.Query<User>().Where(x => x.Name.ToUpper() == "BOB").ToList();

注意:并不是所有的操作都已经实现了。

 

查询提供

 

Query<T>

查找用户id大于50的所有用户,按名称排序,只返回20个记录。

1 var users = db.Query<User>()2    .Where(x => x.UserId > 50)3    .OrderBy(x => x.Name)4    .Limit(20, 40)5    .ToList();

注意:

查询将只在ToList()、ToEnumerable()或返回1值的标量方法中运行。

 

UpdateMany<T>

在必要的情况下,使用 Where 更新所有类型T 。

var list = new[] {1, 2, 3, 4};// 只更新模板传递的(1、2、3、4)中 UserId 对象的 Name字段// 如果使用 ExecuteDefaults 方法,则不会设置默认属性 null,或为0的intdb.UpdateMany<User>()    .Where( x => x.UserId.In(list))    //.ExcludeDefaults()    .OnlyFields(x => x.Name)    .Execute(new User() {Name = "test"});

注意:

查询只在执行调用时运行。

 

DeleteMany<T>

在必要的情况下,使用 Where 删除所有类型T 。

1 var list = new[] {1, 2, 3, 4};2 3 db.DeleteMany<User>()4     .Where(x => list.Contains(x.UserId))5     .Execute();

注意:

查询只在执行调用时运行。

 

版本列支持

 

[VersionColumn]

一个数字字段可以用来检测相互冲突的更新:

1 [TableName("Users")]2 [PrimaryKey("UserId")]3 public class User4 {5     public int UserId { get;set; }6 7     [VersionColumn("VersionInt", VersionColumnType.Number)]8     public long VersionInt { get; set; }9 }

更新将自动检查和增加版本,如果它已经过时,就会抛出 DBConcurrencyException 异常。

这可以通过设置来禁用:VersionException = VersionExceptionHandling.Ignore。

 

在SQL Server中,rowversion timestamp 数据类型

可用于与VersionColumnType.RowVersion版本列:

1 [TableName("Users")]2 [PrimaryKey("UserId")]3 public class User4 {5     public int UserId { get;set; }6 7     [VersionColumn("Version", VersionColumnType.RowVersion)]8     public byte[] Version { get; set; }9 }

 

Sql模板

 

您可以使用SqlBuilder在有条件的地方建立查询,例如,列,orderby等。

1 var sqlBuilder = new SqlBuilder();2 var template = sqlBuilder.AddTemplate("select * from users where age > @0 and /**where**/", 10);

这里你可以指定一个 Where、Select、Join、LeftJoin、OrderBy、OrderByCols、GroupBy 和 Having 相应的sql令牌在下面指定。

 1 /// Adds a filter. The Where keyword still needs to be specified. Uses /**where**/ 2     public SqlBuilder Where(string sql, params object[] parameters) 3  4     /// Replaces the Select columns. Uses /**select**/ 5     public SqlBuilder Select(params string[] columns) 6  7     /// Adds an Inner Join. Uses /**join**/ 8     public SqlBuilder Join(string sql, params object[] parameters) 9 10     /// Adds a Left Join. Uses /**leftjoin**/11     public SqlBuilder LeftJoin(string sql, params object[] parameters)12 13     /// Adds an Order By clause. Uses /**orderby**/14     public SqlBuilder OrderBy(string sql, params object[] parameters)15 16     /// Adds columns in the Order By clause. Uses /**orderbycols**/17     public SqlBuilder OrderByCols(params string[] columns)18 19     /// Adds a Group By clause. Uses /**groupby**/20     public SqlBuilder GroupBy(string sql, params object[] parameters)21 22     /// Adds a Having clause. Uses /**having**/23     public SqlBuilder Having(string sql, params object[] parameters)

语句可以被链接,并且每个新语句的参数从0开始。

1 sqlBuilder2     .Where("height >= @0", 176)3     .Where("weight > @0 and weight < @1", 30, 60);4 5 var db = new Database("conn");6 db.Fetch<User>(template);

可以在任何可以使用Sql类的地方使用模板。

 

 

 

到此为止,wiki 主页上的文章除了一篇讲调试的,还有右侧列表中有二,三篇没有翻译。

翻译过程中挺难受的,英语看的一知半解,代码也一知半解,经常看完代码才明白英文意思。。

不过还好是翻译的意思都差不多,可能会有理解,翻译错误的地方,有发现的园友还请指出,以便改正。

 

翻译时间  2017/8/20

原创粉丝点击