威尼斯人线上娱乐

学习笔记3,Net下无敌的O帕杰罗M

1 4月 , 2019  

阻止并发下的产品超卖思路是选择redis串行处理数据,但又有高产出处理数量的能力

ServiceStack.OrmLite 笔记2

那篇主要介绍 扩展

db.Insert(new Employee { Id = 一, Name = “Employee 1” }); //默承认步

await db.InsertAsync(new Employee { Id = 一, Name = “Employee 一” });
//异步 别的的异步类似那里的这一个示例

db.InsertOnly(new Person { FirstName = “Amy” }, q => q.Insert(p =>
new {p.FirstName}))
// 插入部分字段 后边的参数q.Insert代表要插入的字段 生成sql: INSE宝马X5T INTO
“Person” (“FirstName”) VALUES (‘Amy’)

var rowId = db.Insert(new Poco { Text = “Text” },
selectIdentity:true);// selectIdentity:true重临自拉长的id

学习笔记3,Net下无敌的O帕杰罗M。此处代码有点多 全局的插入时过滤 类似的有UpdateFilter
,感觉正是插入时对数据开始展览阻挠,能够表明您的设想,比如能够在此间加日志,恐怕扩展新的字段,做爱做的事体。
public interface IAudit
{
DateTime CreatedDate { get; set; }
DateTime ModifiedDate { get; set; }
string ModifiedBy { get; set; }
}

//表对应的类
public class AuditTableA : IAudit
{
public AuditTableA()
{
this.CreatedDate = this.ModifiedDate = DateTime.UtcNow;
}

    [AutoIncrement]
    public int Id { get; set; }
    public DateTime CreatedDate { get; set; }
    public DateTime ModifiedDate { get; set; }
    public string ModifiedBy { get; set; }
}

OrmLiteConfig.InsertFilter = (dbCmd, row) => {
var auditRow = row as IAudit;
if (auditRow != null)
auditRow.CreatedDate = auditRow.ModifiedDate = DateTime.UtcNow;
};
上面是下边方法的新体位,也来自官网。对数据开始展览求证
OrmLiteConfig.InsertFilter = OrmLiteConfig.UpdateFilter = (dbCmd, row)
=> {
var auditRow = row as IAudit;
if (auditRow != null && auditRow.ModifiedBy == null)
throw new ArgumentNullException(“ModifiedBy”);
};

try
{
db.Insert(new AuditTable());
}
catch (ArgumentNullException) {
//throws ArgumentNullException
}

db.Insert(new AuditTable { ModifiedBy = “Me!” }); //succeeds

上边包车型的士代码因为也有insert 就也放上吧
在表被创建只怕去除的时候实施sql语句
[PostCreateTable(“INSERT INTO TableWithSeedData (Name) VALUES (‘Foo’);”

  • “INSERT INTO TableWithSeedData (Name) VALUES (‘Bar’);”)]
    public class TableWithSeedData
    {
    [AutoIncrement]
    public int Id { get; set; }
    public string Name { get; set; }
    }

typeof(TableWithSeedData)
.AddAttributes(new PostCreateTableAttribute(
“INSERT INTO TableWithSeedData (Name) VALUES (‘Foo’);” +
“INSERT INTO TableWithSeedData (Name) VALUES (‘Bar’);”));

前戏和事后,都以能够有谈得来的玩法
[PreCreateTable(runSqlBeforeTableCreated)][PostCreateTable(runSqlAfterTableCreated)]
[PreDropTable(runSqlBeforeTableDropped)][PostDropTable(runSqlAfterTableDropped)]
public class Table {}

Db.ExecuteSql(“INSERT INTO page_stats (ref_id, fav_count) VALUES
(@refId, @favCount)”, new { refId, favCount }) //直接执行sql语句

Db.ExecuteSqlAsync(“UPDATE page_stats SET view_count = view_count + 一WHERE id = @id”, new { id })//直接实施sql语句

创建表

前壹篇忘记写创设表了,那里补上。(其实前1篇也有那么一些)

提出安装源码里的t四模板看看效果先。

public 的习性才有效

在表被创立恐怕去除的时候实施sql语句
[PostCreateTable(“INSERT INTO TableWithSeedData (Name) VALUES (‘Foo’);”

  • “INSERT INTO TableWithSeedData (Name) VALUES (‘Bar’);”)]
    public class TableWithSeedData
    {
    [AutoIncrement]
    public int Id { get; set; }
    public string Name { get; set; }
    }

typeof(TableWithSeedData)
.AddAttributes(new PostCreateTableAttribute(
“INSERT INTO TableWithSeedData (Name) VALUES (‘Foo’);” +
“INSERT INTO TableWithSeedData (Name) VALUES (‘Bar’);”));

前戏和之后,都是能够有友好的玩法
[PreCreateTable(runSqlBeforeTableCreated)][PostCreateTable(runSqlAfterTableCreated)]
[PreDropTable(runSqlBeforeTableDropped)][PostDropTable(runSqlAfterTableDropped)]
public class Table {}

public class PocoTable
{
public int Id { get; set; }

[CustomField("CHAR(20)")] //这里是数据库的类型的字段的验证,和fluentvalidation 不太一样,fluentvalidation更多是对类的字段验证。 这里的 [CustomField("CHAR(20)")]是和ef差不多,是指和数据库的映射
public string CharColumn { get; set; }

[CustomField("DECIMAL(18,4)")]
public decimal? DecimalColumn { get; set; }

}
db.CreateTable();
生成sql:
CREATE TABLE “PocoTable”
(
“Id” INTEGER PRIMARY KEY,
“CharColumn” CHAR(20) NULL,
“DecimalColumn” DECIMAL(18,4) NULL
);

//外键和引用 提出协调建多少个表,亲手撸一下。av看再多,比不上约个来一发
public class TableWithAllCascadeOptions
{
[AutoIncrement] public int Id { get; set; }

[References(typeof(ForeignKeyTable1))]
public int SimpleForeignKey { get; set; }

[ForeignKey(typeof(ForeignKeyTable2), OnDelete = "CASCADE", OnUpdate = "CASCADE")]
public int? CascadeOnUpdateOrDelete { get; set; }

[ForeignKey(typeof(ForeignKeyTable3), OnDelete = "NO ACTION")]
public int? NoActionOnCascade { get; set; }

[Default(typeof(int), "17")]  //默认值
[ForeignKey(typeof(ForeignKeyTable4), OnDelete = "SET DEFAULT")]
public int SetToDefaultValueOnDelete { get; set; }

[ForeignKey(typeof(ForeignKeyTable5), OnDelete = "SET NULL")]
public int? SetToNullOnDelete { get; set; }

}

db.DropAndCreateTable();//删除然后添加表
dbFactory.Run(db => db.CreateTable(overwrite:false));//不解释
看姿势
db.CreateTable(true);// overwrite 直给

//批量添加 用工作
db.DropAndCreateTable();
var rows = “A,B,B,C,C,C,D,D,E”.Split(‘,’).Map(x => new
LetterFrequency { Letter = x });
db.InsertAll(rows);

贯彻在此间
internal static void InsertAll(this IDbCommand dbCmd, IEnumerable
objs)
{
IDbTransaction dbTrans = null;

        try
        {
            if (dbCmd.Transaction == null)
                dbCmd.Transaction = dbTrans = dbCmd.Connection.BeginTransaction();

            var dialectProvider = dbCmd.GetDialectProvider();

            dialectProvider.PrepareParameterizedInsertStatement<T>(dbCmd);

            foreach (var obj in objs)
            {
                if (OrmLiteConfig.InsertFilter != null)
                    OrmLiteConfig.InsertFilter(dbCmd, obj);

                dialectProvider.SetParameterValues<T>(dbCmd, obj);

                try
                {
                    dbCmd.ExecNonQuery();
                }
                catch (Exception ex)
                {
                    Log.Error("SQL ERROR: {0}".Fmt(dbCmd.GetLastSqlAndParams()), ex);
                    throw;
                }
            }

            if (dbTrans != null)
                dbTrans.Commit();
        }
        finally
        {
            if (dbTrans != null)
                dbTrans.Dispose();
        }
    }

一,介绍:Dapper是1款轻量级O卡宴M工具。假设你在小的门类中,使用Entity
Framework、NHibernate
来处理大数目访问及涉及映射,未免有点杀鸡用牛刀。你又以为OWranglerM省时仔细,那时Dapper
将是你不贰的选料。

产品表(product) 

  —ORubiconM框架的宗旨绪想是目的关系映射,OLacrosseM是将表与表之间的操作,映射成对象和对象时期的操作,正是经过操作实体类来达成操作表的指标。从数据库提取的数据会自动按你设置的照射供给封装成特定的目的。之后您就足以因此对目的举办操作来修改数据库中的数据。那时候你面对的不是新闻的零散,而是2个形象显著的目的。

class Product

2,假诺你欣赏原生的Sql语句,又喜欢O宝马X3M的简要,那你势必会欣赏上Dapper,那款ROMDapper的优势:

{

  1. 轻量。唯有八个文本(SqlMapper.cs),编写翻译实现之后只有120k(好象是变胖了)
  2. 速度快。Dapper的快慢接近与IDataReader,取列表的数量超过了DataTable。
  3. 扶助二种数据库。Dapper能够在具备Ado.net Providers下工作,包含sqlite,
    sqlce, firebird, oracle, MySQL, PostgreSQL and SQL Server
  4. 能够映射1对1,壹对多,多对多等五种关系。
  5. 属性高。通过Emit反射IDataReader的队列队列,来极快的获得和产生对象,品质不错。
  6. 支持FrameWork2.0,3.0,3.5,4.0,4.5  

  public int Id{get;set} //自增Id

上面介绍Dapper如何使用,来展开高效开发,以下操作是编写翻译后在Net三.5下操作的例证,Net四.0下大多数函数有默许值,参数很容易。

       public string Name{get;set}//产品名称

三, 为何要推而广之Dapper?

       public int Number{get;set}//库存

精通Dapper都晓得,在挥洒代码时,大家如故会手动写SQL,扩展的指标就是在一点一滴不改变dapper源代码和使用基础上,实行3回封闭,达到零SQL,达成完全对象操作。

       public DateTime NTime{get;set;}//仓库储存同步时间

四,原生Dapper使用流程:

       ….

  0,二种下载应用办法:

}

  (1),推荐下载情势(使用Nuget下载):

仓库储存变更记录表(productNumberRecord)

  —Nuget是3个.NET阳台下的开源的花色,它是Visual
Studio的扩张。在行使Visual Studio开发基于.NET
Framework的运用时,Nuget能把在品种中加上、移除和立异引用的做事变得尤为火速方便。

class productNumberRecord

威尼斯人线上娱乐 1

{

—安装成功未来,生成一下网站,项目bin目录下,会变动多少个Dapper文件(重若是Dapper.dll,120k)。

  public int Id{get;set;}

  (贰),能够在官网上下载Dapper源代码,即SqlMapper.cs文件,在品种中App_Code文件夹中出席这几个文件,仿佛Ado.net中的SqlHelper一样。

       public int Number{get;set;} //这一次消耗仓库储存数据

  —源文件地方:

       public int SurplusNumber{get;set} //本次消耗后的盈余数量

  一,上边能够在类型中初露利用Dapper了

       public DataTime 提姆e{get;set;} //记录时间

  2,连接数据库字符串``。根据不同的数据库进行相应设置,如果是SQL,就类似下边设置;如果是使用SQLite,则设置方法不同。

       ….

private readonly string sqlconnection =
                 "Data Source=RENFB;Initial Catalog=test;User Id=sa;Password=sa;";
//public readonly string mysqlconnectionString =
                 @"server=127.0.0.1;database=test;uid=renfb;pwd=123456;charset='gbk'";

}

  3,获取Sql Server的连接数据库对象。

一.将产品Id,仓库储存存入redis,每回操作产品仓库储存,则发出一条仓库储存的更改记录存入sql库中

public SqlConnection OpenConnection()
{
    SqlConnection connection = new SqlConnection(sqlconnection); 
//那里sqlconnection就是数据库连接字符串
    connection.Open();
    return connection;
}
//获取MySql的延续数据库对象。MySqlConnection
//public MySqlConnection OpenConnection()
//{
//     MySqlConnection connection = new
MySqlConnection(mysqlconnectionString);
//     connection.Open();
//     return connection;
//}

二.那时候sql库产品的实在仓库储存应该是 仓库储存=仓库储存-仓库储存记录(大于NTime时间的记录)

注:假使须要换来Mysql数据库,只用将获得sql
Server的连日数据库对象的函数注释掉,撤销MySql的连年数据库对象的函数的诠释,1并裁撤Mysql连接字符串的注明,并修改为友好的接连音信。

3.sql库中的余额,可以做定时任务按天或时辰数实行同步,制止过大的记录造成select超时

Query()方法:
Query()是IDbConnection增添方法并且重载了,从数据Curry提取新闻,并用来填充大家的事体对象模型。

四.假设redis挂掉,那么它将从数据库中 依据步揍2的法子1并仓库储存

  肆,//先创设1个类,是数据库的user表的模型。
  public class user
     {
        public int id { get; set; }
        public string name { get; set; }
        public string address { get; set; }
        public string age { get; set; }
     }
伍,手写Sql插入数据(增)

 

    /// <summary>
        /// 手写Sql插入数据
        /// </summary>
        public int InsertWithSql()
        {
            using (var conn = SQLiteHelper.OpenConnection()) 
//这里走访的是Sqlite数据文件,那里OpenConnection即上面获取连接数据库对象方法
            {
                user user=new user();
                user.name = “Dapper01”;
                user.address = “周口”;
                user.age=”15″;
  //string _sql = “INSERT INTO
User(name,address,age)VALUES(‘Dapper01′,’周口’,13)”;
string _sql = “INSERT INTO
User(name,address,age)VALUES(@name,@address,@age)”;
                return conn.Execute(_sql,user);
            }
        }

伪代码完毕(不加锁)

    —假诺不用Dapper,用插入一条数据要求多少代码量(相对上面只用了二行代码,上面要求用6行代码):

(起始业务){

   public static int insert_news(string title, string content)
    {
        string sql = “insert into news(title,content,addtime)
values(@title,@content,@addtime)”;
        SQLiteParameter[] parameters =
            {
                SQLiteHelper.MakeSQLiteParameter(“@title”,
DbType.String, title.Trim()),
                SQLiteHelper.MakeSQLiteParameter(“@content”,
DbType.String, content.Trim()),
                SQLiteHelper.MakeSQLiteParameter(“@addtime”,
DbType.DateTime,DateTime.Now)
            };
        return SQLiteHelper.ExecuteSql(sql, parameters); 
//调用SQLiteHelper文件中艺术,执行数据库插入
    }

try{

六,手写Sql输出数据(删)

func壹(插入变更记录表);
若是func1 执行破产 间接跳出

protected void Page_Load(object sender, EventArgs e)
        {
            user user = new user();
            user.id = 15;
            DeleteColumn(user);
        }
//删除三个档次(三行):
        public int DeleteColumn(user user)
        {
            using (IDbConnection conn = SQLiteHelper.OpenConnection())
            {
                const string query = “delete from user where id=@id”;
                return conn.Execute(query, user);
            }
        }

func3 …

  —不用Dapper,删除一条数据,代码如下(4行):

func4 …

  public static int del_news(string newid)
    {
        string sql = “delete from news where newid=@newid”;
        SQLiteParameter[] parameters =
            {
                SQLiteHelper.MakeSQLiteParameter(“@newid”,
DbType.String, newid.Trim())
            };
        return SQLiteHelper.ExecuteSql(sql, parameters);
    }

等其它工作

七,手写Sql更新数据(改)

funcX(增减redis库存)
一经funcX执行破产,直接跳出,不插入日志

protected void Page_Load(object sender, EventArgs e)
        {
            user user = new user();
            user.id = 14;
            user.name = “Dapper03”;
            user.address = “太康”;
            user.age = “25”;
            UpdateColumn(user);
        }

假使都成功 则交给业务

//更新多少个品种:
        public int UpdateColumn(user user)
        {
            using (IDbConnection conn = SQLiteHelper.OpenConnection())
            {
                const string query = “update user set
name=@name,address=@address,age=@age where id=@id”;
                return conn.Execute(query, user);
            }
        }

catch{
tran.callback()//事务回滚
}

八,手写Sql查询数据(查)

 

protected void Page_Load(object sender, EventArgs e)
        {
            user user = new user();
            user.id = 14;
            user=SelectColumn(user.id);
           
Context.Response.Write(user.name+”|”+user.address+”|”+user.age);
            Context.Response.End();
        }

//获取单个user对象。
        public user SelectColumn(int user_id)
        {
            using (IDbConnection conn = SQLiteHelper.OpenConnection())
            {
                const string query = “select * from user where
id=@id”;
                return conn.Query<user>(query, new {id =
user_id}).SingleOrDefault<user>(); 
//这里用的是linq语法,所以必须引用System.Linq;
            }
        }

  —那里大家传递了2个参数给Query方法,参数能够是此外对象,其个性在询问中与sql的参数匹配,由于Query总是回到三个集聚,大家只需调用SingleOrDefault方法,因为我们领会总是重回0或一行.

//获取user对象的聚众。
        public IEnumerable<user> SelectUsers()
        {
            using (IDbConnection conn = SQLiteHelper.OpenConnection())
            {
                const string query = “select * from user order by id
asc”;
                return conn.Query<user>(query, null);
            }
        }

    protected void Page_Load(object sender, EventArgs e)
        {
            IEnumerable<user> list = SelectUsers();
            foreach (var i in list)
            {
                Context.Response.Write(i.name + “|” + i.address + “|” +
i.age);
                Context.Response.Write(“<br/>”);
            }
            Context.Response.End();
        }

5,如若想直接插入二个实体对象,Sql语句都并非了,能够在Nuget上下载Dapper的扩大包—>Dapper.SimpleCRUD安装包。(crud即增查改删)

—使用Dapper.SimpleCRUD时,八个注意点,1是直接插入实体,类代码要改:

  public class user
    {
[Key] //主键值前加个key
        public int id { get; set; }
        public string name { get; set; }
        public string address { get; set; }
        public string age { get; set; }
    }

       ///<summary>
         ///实体插入数据
         ///</summary>
        public int? InsertWithEntity()
        {
            using (var conn = SQLiteHelper.OpenConnection())
            {
                var user = new user { name = “Dapper02”, address =
“周口”,age=”22″};
                return conn.Insert(user);
            }
        } 

  —二是使用sqlite数据库时,会报错!错误内容如下,因为sqlite不辅助scope_identity函数,没有这些函数:

SQL logic error or missing database no such function: SCOPE_IDENTITY

伍,便是如此不难,直接在例子中放置Sql,很不难扩充为存款和储蓄进度,能够运用小名使结果集中的列与作业对象模型(ColumnCat)的性质对应。

//下面使用上面的集合显示出分类。List<ColumnCat> AllColumnCat =SelectColumnCats().ToList<ColumnCat>();foreach (ColumnCat cat in AllColumnCat.Where(c => c.Parentid == 0)){    Response.Write("Name==>" + cat.Name + "\t");    Response.Write("时间==>" + cat.ModifiedOn + "\t");    Response.Write("<br/>");    foreach (ColumnCat c in AllColumnCat                .Where<ColumnCat>(subColumnCat => subColumnCat.Parentid == cat.Id))    {        Response.Write("&nbsp;&nbsp;++++");        Response.Write("Name==>" + c.Name + "\t");        Response.Write("时间==>" + c.ModifiedOn + "\t");        Response.Write("<br/>");    }}

//将一级类别和二级类别显示在页面上,如果使用一个递归,很容易实现无限级分类(你懂的)。

7,//Dapper也可以加载填充嵌套对象,考虑那样壹种情状,考虑到音讯的品类属性,重返种类对象,
//我们创设一个Column的类
public class Column
{
    public int Id { get; set; }
    public string Name { get; set; }
    public DateTime ModifiedDate { get; set; }
    public ColumnCat ColumnCat { get; set; }
}

//接下去大家来填充大家的作业对象。
public IList<Column> SelectColumnsWithColumnCat()
{
    using (IDbConnection conn = OpenConnection())
    {
        const string query = “select
c.Id,c.Name,c.ModifiedDate,c.ColumnCatid
        ,cat.id,cat.[Name],cat.ModifiedOn,cat.Parentid from [Column]
as c
        left outer join ColumnCat as cat on c.ColumnCatid=cat.id”;
        return conn.Query<Column, ColumnCat, Column>(query
               , (column, columncat) => { column.ColumnCat =
columncat; return column; }
               , null, null, false, “Id”, null,
null).ToList<Column>();
    }
}

  注:1,在填写嵌套对象的时候,只可以执行
ToList<>方法,不然回报ExecuteReader
须要已开辟且可用的连日。连接的脚下情况为已关闭,而单个对象不会报错,估摸是using甘休后关门了连接,而嵌套对象在map的时候又举办了
ExecuteReader,只可以在using停止从前重临list集合。
贰,嵌套对象的参数是相比多的,主借使前几个参数,别的参数没用能够设置为null,可是在四.0版本能够只写七个参数,别的参数都有暗中认可值。特别要注意
的是splitOn,那么些参数不能够为空,不然会报对象为引用的错误。【splitOn参数的情趣是读取第二个对象的的分割列,从哪个列起早先读取第三个对
象,假诺表里的自增进列都为Id,能够安装这几个参数为”Id”】.

  Execute方法:
正如Query方法是寻找数据的,Execute方法不会寻找数据,它与Query方法丰富相似,但它总再次来到总数(受影响的行数),而不是一个目标集合【如:insert
update和delete】.

八,//接下去向数据Curry添加三个体系
public int InsertColumnCat(ColumnCat cat)
{
    using (IDbConnection conn = OpenConnection())
    {
        const string query = “insert into
ColumnCat([name]威尼斯人线上娱乐 ,,ModifiedOn,Parentid)
        values (@name,@ModifiedOn,@Parentid)”;
        int row = conn.Execute(query,cat);
       
//更新对象的Id为数据Curry新增的Id,借使扩展之后不供给取得新增的对象,
        //只需将对象添加到数据Curry,能够将上面包车型客车1行注释掉。
        SetIdentity(conn,id=>cat.Id=id,”id”,”ColumnCat”);   
        return row;
    }
}
public void SetIdentity(IDbConnection conn, Action<int>
setId,string primarykey
                          ,string tableName)
{
    if (string.IsNullOrEmpty(primarykey)) primarykey = “id”;
    if (string.IsNullOrEmpty(tableName))
    {
        throw new
ArgumentException(“tableName参数不能够为空,为查询的表名”);
    }
    string query = string.Format(“SELECT max({0}) as Id FROM {1}”,
primarykey
                         , tableName);
    NewId identity = conn.Query<NewId>(query,
null).Single<NewId>();
    setId(identity.Id);
}
public class NewId
{
    public int Id { get; set; }
}

  由于Dapper是经过类的品质自动绑定的,所以扩张了NewId类来得到增添对象后的Id,本来打算选拔@@identity,Net3.五下使用总是报错,只能动用马克斯函数获取。当然假若不须求得到更新后的对象的ID,能够不使用SetIdentity,这一个函数通用。

编写翻译Dapper源码生成的是Net四.0下选用的,能够依靠Net4.0新增的dynamic动态类型,
//SetIdentity的落到实处将那多少个有益。如下:
public void SetIdentity<T>(IDbConnection conn, Action<int>
setId)
{
    dynamic identity = connection.Query(“SELECT @@IDENTITY AS
Id”).Single();
    T newId = (T)identity.Id;
    setId(newId);
}
玖,上边介绍一下Dapper的高等用法
//Dapper对事务处理的事例,如删减类其余同时删除类别下的装有情报。可能去除产品的还要,
//删除产品图片表里关联的全数图片。
public int DeleteColumnCatAndColumn(ColumnCat cat)
{
    using (IDbConnection conn = OpenConnection())
    {
        const string deleteColumn = “delete from [Column] where
ColumnCatid=@catid”;
        const string deleteColumnCat = “delete from ColumnCat where
id=@Id”;
        IDbTransaction transaction = conn.BeginTransaction();
        int row=conn.Execute(deleteColumn, new { catid
=cat.Id},transaction,null,null);
        row += conn.Execute(deleteColumnCat, new {
id=cat.Id},transaction,null,null);
        transaction.Commit();
        return row;
    }
}


相关文章

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图