Firebird Fluentdata

Fluentdata 支持很多种数据库驱动,但对Firebird不友好,不过可以使用DB2Provider来操作大部分功能,

例如: new DbContext().ConnectionString(connectionString, new DB2Provider(), FirebirdClientFactory.Instance) 

但是对于Insert后获取自动生成的最大Id,就会报错,因为DB2的语法不通。

起初怀疑获取最大Id方法是通过自动添加select max(id)来获取,这样就有可能访问量大时会存在错误。

好在官网有源码可以查看,结果不是的。

每种数据库都有insert后获取inserted记录的Id的方法,Firebird也不例外,语法是: insert A (x,x) values (x,x) returning id, x, x 和Oracle语法差不多。

那就果断添加一个 FirebirdProvider ,后续我们再查看下其他各数据库ExecuteReturnLastId的具体做法。

FirebirdProvider 代码:

  1 using System;
  2 using System.Collections.Generic;
  3 using System.Data;
  4 using System.Linq;
  5 using System.Text;
  6 using FluentData.Providers.Common;
  7 using FluentData.Providers.Common.Builders;
  8 
  9 namespace FluentData
 10 {
 11     public class FirebirdProvider: IDbProvider
 12     {
 13         public string ProviderName
 14         {
 15             get
 16             {
 17                 return "FirebirdSql.Data.FirebirdClient";
 18             }
 19         }
 20 
 21         public bool SupportsOutputParameters
 22         {
 23             get { return true; }
 24         }
 25 
 26         public bool SupportsMultipleResultsets
 27         {
 28             get { return true; }
 29         }
 30 
 31         public bool SupportsMultipleQueries
 32         {
 33             get { return true; }
 34         }
 35 
 36         public bool SupportsStoredProcedures
 37         {
 38             get { return true; }
 39         }
 40 
 41         public bool RequiresIdentityColumn
 42         {
 43             get { return false; }
 44         }
 45 
 46         public IDbConnection CreateConnection(string connectionString)
 47         {
 48             return ConnectionFactory.CreateConnection(ProviderName, connectionString);
 49         }
 50 
 51         public string GetParameterName(string parameterName)
 52         {
 53             return "@" + parameterName;
 54         }
 55 
 56         public string GetSelectBuilderAlias(string name, string alias)
 57         {
 58             return name + " as " + alias;
 59         }
 60 
 61         public string GetSqlForSelectBuilder(SelectBuilderData data)
 62         {
 63             var sql = "";
 64             sql = "select " + data.Select;
 65             sql += " from " + data.From;
 66             if (data.WhereSql.Length > 0)
 67                 sql += " where " + data.WhereSql;
 68             if (data.GroupBy.Length > 0)
 69                 sql += " group by " + data.GroupBy;
 70             if (data.Having.Length > 0)
 71                 sql += " having " + data.Having;
 72             if (data.OrderBy.Length > 0)
 73                 sql += " order by " + data.OrderBy;
 74             if (data.PagingItemsPerPage > 0
 75                 && data.PagingCurrentPage > 0)
 76             {
 77                 sql += string.Format(" rows {0} to {1}", data.GetFromItems(), data.GetToItems());
 78             }
 79 
 80             return sql;
 81         }
 82 
 83         public string GetSqlForInsertBuilder(BuilderData data)
 84         {
 85             return new InsertBuilderSqlGenerator().GenerateSql(this, "@", data);
 86         }
 87 
 88         public string GetSqlForUpdateBuilder(BuilderData data)
 89         {
 90             return new UpdateBuilderSqlGenerator().GenerateSql(this, "@", data);
 91         }
 92 
 93         public string GetSqlForDeleteBuilder(BuilderData data)
 94         {
 95             return new DeleteBuilderSqlGenerator().GenerateSql(this, "@", data);
 96         }
 97 
 98         public string GetSqlForStoredProcedureBuilder(BuilderData data)
 99         {
100             return data.ObjectName;
101         }
102 
103         public DataTypes GetDbTypeForClrType(Type clrType)
104         {
105             return new DbTypeMapper().GetDbTypeForClrType(clrType);
106         }
107 
108         public object ExecuteReturnLastId<T>(IDbCommand command, string identityColumnName = null)
109         {
110             if (identityColumnName == null) identityColumnName = "id";
111 
112             string temp = command.Data.Sql.ToString().Trim();
113             if (temp.EndsWith(";"))
114                 command.Data.Sql.Clear().Append(temp.Substring(0, temp.Length - 1));
115 
116             command.ParameterOut("FluentDataLastId", command.Data.Context.Data.FluentDataProvider.GetDbTypeForClrType(typeof(T)));
117             command.Sql(" returning " + identityColumnName);
118 
119 
120             object lastId = null;
121 
122             command.Data.ExecuteQueryHandler.ExecuteQuery(false, () =>
123             {
124                 command.Data.InnerCommand.ExecuteNonQuery();
125 
126                 lastId = command.ParameterValue<object>("FluentDataLastId");
127             });
128 
129             return lastId;
130         }
131 
132         public void OnCommandExecuting(IDbCommand command)
133         {
134         }
135 
136         public string EscapeColumnName(string name)
137         {
138             return name;
139         }
140     }
141 }

具体调用方法: new DbContext().ConnectionString(connectionString, new FirebirdProvider(), FirebirdClientFactory.Instance) 

DB2做法是: select IDENTITY_VAL_LOCAL() as LastId from sysibm.sysdummy1; 

Mysql做法是: select LAST_INSERT_ID() as `LastInsertedId` 

Oracle做法是:sql结尾添加输出参数   returning id into :FluentDataLastId 

PgSql做法是: select lastval(); 

Sqlite做法是: select last_insert_rowid(); 

SqlCe做法是: select cast(@@identity as int) 

SqlServer做法是: select SCOPE_IDENTITY() 

 ===================================================

实体方法扩展:

 1     public class Base
 2     {
 3         public long id { get; set; }
 4     }
 5 
 6     public class T_session : Base
 7     {
 8         public string token { get; set; }
 9         public long? user_id { get; set; }
10         public DateTime login_time { get; set; }
11         public DateTime? logout_time { get; set; }
12         public DateTime update_time { get; set; }
13     }
14 
15     public static class DbExt
16     {
17         public static long Insert(this Base enty, IDbContext db)
18         {
19             return db.Insert(enty.GetType().Name, enty).AutoMap(x => x.id).ExecuteReturnLastId<long>();
20         }
21 
22         public static int Update(this Base enty, IDbContext db)
23         {
24             return db.Update(enty.GetType().Name, enty).AutoMap(x => x.id).Where(x => x.id).Execute();
25         }
26 
27         public static int Delete(this Base enty, IDbContext db)
28         {
29             return db.Delete(enty.GetType().Name, enty).Where(x => x.id).Execute();
30         }
31 
32     }
原文地址:https://www.cnblogs.com/jonney-wang/p/9634048.html