public void UpdateEndTime(Database db) { db.ExecNonQuery( string.Format("update {0} set {1}=?time where {2}=?id", Mapper.TableName, Mapper.EndTime, Mapper.PickId) , new string[]{ "time", "id" } , new object[]{ this.EndTime, this.PickId }); }
public static Stock Get(Database db, int id) { DataSet ds = db.ExecDataSet( string.Format("select * from {0} where {1}=?id", Mapper.TableName, Mapper.StockId), new string[]{"id"}, new object[]{ id } ); if(ds==null || ds.Tables.Count<=0 || ds.Tables[0].Rows.Count<=0) return null; return new Stock(ds.Tables[0].Rows[0]); }
public static IList<KTrendMALong> FindAll(Database db, int stoId) { DataSet ds = KTrend.FindAll(db, TABLE_NAME, stoId); IList<KTrendMALong> result = new List<KTrendMALong>(ds.Tables[0].Rows.Count); foreach(DataRow row in ds.Tables[0].Rows){ result.Add(new KTrendMALong(row)); } return result; }
public void Create(Database db) { db.ExecNonQuery( string.Format( "insert into {0} ({1},{2},{3}) values(?id, ?code, ?name)" , Mapper.TableName, Mapper.StockId, Mapper.StockCode, Mapper.StockName ) , new string[] {"id","code","name"} , new object[] {this.StockId, this.StockCode, this.StockName}); }
public static IList<Stock> FindAll(Database db) { List<Stock> result = new List<Stock>(); DataSet ds = db.ExecDataSet(string.Format("select * from {0}", Mapper.TableName), null, null); if(ds.Tables.Count<=0 || ds.Tables[0].Rows.Count<=0) return result; foreach(DataRow row in ds.Tables[0].Rows){ result.Add(new Stock(row)); } return result; }
void BtnGenChartKTrendClick(object sender, EventArgs e) { Database db = new Database(this.txtDatabase.Text); db.Open(); Pandora.Invest.Html.HtmlChartGenerate.GenerateMALineChart (db, int.Parse (this.txtStockCode.Text), DateTime.Parse (this.txtStartDate.Text), DateTime.Parse (this.txtEndDate.Text) ); db.Close(); }
public void Create(Database db) { db.ExecNonQuery( string.Format( "insert into {0} ({1},{2},{3},{4},{5}) values(?strategy, ?stime, ?etime, ?mode, ?param)" , Mapper.TableName, Mapper.Strategy, Mapper.StartTime, Mapper.EndTime, Mapper.PickingMode, Mapper.Params ) , new string[] {"strategy","stime","etime", "mode", "param"} , new object[] {this.Strategy, this.StartTime, this.EndTime, this.PickingMode, this.Params}); this.PickId = Convert.ToInt32(db.ExecScalar("select last_insert_id()", null, null)); }
internal BulkUpdate(Database db, string table, string[] valueColumns, string[] idColumns, int batchSize) { this._db = db; if(string.IsNullOrEmpty(table) || table.Trim().Length<=0) throw new DatabaseException("Parameter 'table' is empty or null in BulkUpdate"); this._table = table; if(valueColumns==null || valueColumns.Length<=0) throw new DatabaseException("Parameter 'valueColumns' is empty or null in BulkUpdate"); this._valueColumns = valueColumns; if(idColumns==null || idColumns.Length<=0) throw new DatabaseException("Parameter 'idColumns' is empty or null in BulkUpdate"); this._idColumns = idColumns; this._batchSize = batchSize <=0 ? 50 : batchSize; this._valueRows = new List<object[]>(batchSize); this._idRows = new List<object[]>(batchSize); }
public void UpdateInfo(Database db) { db.ExecNonQuery( string.Format( "update {0} set {1}=?date,{2}=?tCap,{3}=?cCap,{4}=?eps,{5}=?navps,{6}=?growth,{7}=?loc,{8}=?plat, {9}=?industry where {10}=?id", Mapper.TableName, Mapper.ListDate, Mapper.TotalCapital, Mapper.CirculatingCapital, Mapper.EarningsPerShare, Mapper.NetAssetValuePerShare, Mapper.NetProfitGrowth, Mapper.CompanyLocation, Mapper.Plate, Mapper.Industry, Mapper.StockId) , new string[]{"date","tCap","cCap","eps","navps","growth","loc","plat","industry","id"} , new object[]{ this.ListDate, this.TotalCapital, this.CirculatingCapital, this.EarningsPerShare, this.NetAssetValuePerShare, this.NetProfitGrowth, this.CompanyLocation, this.Plate, this.Industry, this.StockId }); }
void BtnFilterStockClick(object sender, EventArgs e) { Database db = new Database(this.txtDatabase.Text); db.Open(); IList<Stock> stocks = Stock.FindAll(db); db.Close(); string corssStar = "AM-Open-Close=0.006; AM-Min-Max=0.05; AM-Prev=0.015; AM-Matched-Days=0.03; RatioVolReduce=50; Min-Matched-Days=4; Starting-Point=99999; Regression=true"; IList<StrategyConfig> confList = new List<StrategyConfig>(); confList.Add(new StrategyConfig("MicroPriceTrendStrategy", corssStar)); ProgressStatus status = new ProgressStatus(); this._progressController.Start("执行策略选股...", status); var tm = new MThreadManager<Stock>(THREAD_COUNT, typeof(PickingStrategyWorker), status); tm.SetContext("connection-string", this.txtDatabase.Text) .SetContext("executors", confList) .AddItem(stocks) .Start(); }
/// <summary> /// 批量导入日K线数据。 /// 1. klines只能包含1支股票的日K线数据; /// 2. klines中的数据必须按照交易日期升序排序; /// </summary> /// <param name="db"></param> /// <param name="kdatas"></param> /// <returns></returns> public static int BatchImport(Database db, List<KJapaneseData> kdatas) { if(kdatas==null || kdatas.Count<=0) return 0; try{ int stockId = kdatas[0].StockId; //if(stockId!=998) return 0; //TODO DateTime start = DateTime.Now; //因为要计算250日均线,所以向前加载K线数据 List<KJapaneseData> latest = FindLatest(db, stockId, 251)as List<KJapaneseData>; #region 导入K线数据前的初始化处理 //1.数据库中已经存在K线数据时,将数据库中最新交易日的K线数据删除,这是为了防止在开盘时间导出的K线数据, // 导致当天的K线数据与收盘时不一致,删除重新导入; if(latest.Count>0){ latest[latest.Count-1].Remove(db); latest.RemoveAt(latest.Count-1); } //2.如果数据库中已经存在K线数据,则这些数据不再重新导入; while(kdatas.Count>0 && latest.Count>0 && kdatas[0].TxDate<=latest[latest.Count-1].TxDate){ kdatas.RemoveAt(0); } //3.如果latest中不足250条数据,则用最早的k线数据补全 KJapaneseData cloneTarget = null; int persistedStart = 0; if(latest.Count>0) cloneTarget = latest[0]; else cloneTarget = kdatas[0]; while(latest.Count<250){ latest.Insert(0, cloneTarget.Clone(-1)); persistedStart++; } //4.把本次要导入的数据添加到latest中 int impStart = latest.Count, impEnd = impStart + kdatas.Count - 1; //将需要导入的日K线数据kdatas追加到latest后面,计算过程中改变latest中实体的MA均线价格,这些修改 //同时也会反应到kdatas中的实体上。 //最后将kdatas插入数据库,即完成数据导入 latest.AddRange(kdatas); //5.在latest最后追加16条最新k线数据的拷贝,用于计算定制化的均价、均量 cloneTarget = kdatas[kdatas.Count-1]; long latestEffectiveVol = cloneTarget.Volume; for(int i=kdatas.Count-1; i>=0; i--){ if(!kdatas[i].IsAllDayOnFusingPrice()){ latestEffectiveVol = kdatas[i].Volume; break; } } for(int i=0; i<16; i++){ KJapaneseData cloned = cloneTarget.Clone(1); //1子板涨跌停期间对均量线影响较大,为排除这种影响,克隆对象取最后一个非涨跌停板的成交量 cloned.Volume = latestEffectiveVol; latest.Add(cloned); } #endregion #region 计算标准化MA均线价格 //初始化各均线价格 decimal ma5=0, ma10=0, ma20=0, ma60=0, ma120=0, ma250=0; for(int i=0; i<impStart; i++){ ma250 += latest[i].ClosePrice; if(impStart-i<=120) ma120 += latest[i].ClosePrice; if(impStart-i<=60) ma60 += latest[i].ClosePrice; if(impStart-i<=20) ma20 += latest[i].ClosePrice; if(impStart-i<=10) ma10 += latest[i].ClosePrice; if(impStart-i<=5) ma5 += latest[i].ClosePrice; } for(int i=impStart; i<=impEnd; i++){ //设置上一交易日日期及价格 if(!latest[i-1].IsCloned()){ latest[i].PrevDate = latest[i-1].TxDate; latest[i].PrevPrice = latest[i-1].ClosePrice; } //5日均线价格 ma5 = ma5 + latest[i].ClosePrice - latest[i-5].ClosePrice; latest[i].MA5 = ma5 / 5; //10日均线价格 ma10 = ma10 + latest[i].ClosePrice - latest[i-10].ClosePrice; latest[i].MA10 = ma10 / 10; //20日均线价格 ma20 = ma20 + latest[i].ClosePrice - latest[i-20].ClosePrice; latest[i].MA20 = ma20 / 20; //60日均线价格 ma60 = ma60 + latest[i].ClosePrice - latest[i-60].ClosePrice; latest[i].MA60 = ma60 / 60; //120日均线价格 ma120 = ma120 + latest[i].ClosePrice - latest[i-120].ClosePrice; latest[i].MA120 = ma120 / 120; //250日均线价格 ma250 = ma250 + latest[i].ClosePrice - latest[i-250].ClosePrice; latest[i].MA250 = ma250 / 250; } #endregion CalculateMA(latest, impStart, impEnd, MAType.MAShort); CalculateMA(latest, impStart, impEnd, MAType.MALong); CalculateMA(latest, impStart, impEnd, MAType.VMAShort); CalculateMA(latest, impStart, impEnd, MAType.VMALong); DateTime afterCalc = DateTime.Now; #region 批量导入、更新 db.BeginTransaction(); //批量插入 try{ BulkInserter<KJapaneseData> bi = new KJapaneseDataBulkInserter<KJapaneseData>(db, 200); //初步验证,一批次插入200条性能最好 for(int i=impStart; i<=impEnd; i++) bi.Push(latest[i]); bi.Flush(); //更新受影响的双重9日均线价格 int startIndex = impStart - 8; if(startIndex<0) startIndex = 0; if(startIndex<persistedStart) startIndex = persistedStart; for(int i=startIndex; i<impStart; i++) latest[i].UpdateMA(db); db.CommitTransaction(); }catch(Exception exInner){ db.RollbackTransaction(); log.Error("导入日K线数据错误", exInner); } #endregion return kdatas.Count; }catch(Exception ex){ log.Error("导入日K线错误", ex); return 0; } }
/// <summary> /// 获取最新topRows条K线数据,返回的列表按交易日期<b>【升序】</b>排序。 /// </summary> /// <param name="db"></param> /// <param name="stockId"></param> /// <param name="topRows"></param> /// <returns></returns> public static IList<KJapaneseData> FindLatest(Database db, int stockId, int topRows) { DateTime start = DateTime.Now; DataSet ds = db.ExecDataSet( string.Format("select * from {0} where {1}=?stoId order by {2} desc limit ?rows" , Mapper.TableName, Mapper.StockId, Mapper.TxDate), new string[]{"stoId", "rows"}, new object[]{ stockId, topRows } ); DateTime loaded = DateTime.Now; List<KJapaneseData> result = new List<KJapaneseData>(topRows); if(ds!=null && ds.Tables.Count>0 && ds.Tables[0].Rows.Count>0){ foreach(DataRow row in ds.Tables[0].Rows){ result.Add(new KJapaneseData(row)); } } result.Reverse(); _dbTime += Convert.ToInt64((loaded - start).TotalMilliseconds); _entityTime += Convert.ToInt64((DateTime.Now - loaded).TotalMilliseconds); return result; }
public static IList<KJapaneseData> FindAll(Database db, int stockId) { DataSet ds = db.ExecDataSet( string.Format("select * from {0} where {1}=?stoId" , Mapper.TableName, Mapper.StockId), new string[]{"stoId"}, new object[]{ stockId } ); IList<KJapaneseData> result = new List<KJapaneseData>(); if(ds!=null && ds.Tables.Count>0 && ds.Tables[0].Rows.Count>0){ foreach(DataRow row in ds.Tables[0].Rows){ result.Add(new KJapaneseData(row)); } } return result; }
public static IList<KJapaneseData> Find(Database db, int stockId, DateTime start, DateTime end) { DataSet ds = db.ExecDataSet( string.Format("select * from {0} where {1}=?stoId and {2}>=?start and {2}<=?end order by {2}" , Mapper.TableName, Mapper.StockId, Mapper.TxDate), new string[]{"stoId", "start", "end"}, new object[]{ stockId, start, end } ); List<KJapaneseData> result = new List<KJapaneseData>(ds.Tables[0].Rows.Count); if(ds!=null && ds.Tables.Count>0 && ds.Tables[0].Rows.Count>0){ foreach(DataRow row in ds.Tables[0].Rows){ result.Add(new KJapaneseData(row)); } } return result; }
public static IList<ShareholdersNumEntity> FindLatest(Database db, DateTime startDate) { DataSet ds = db.ExecDataSet( "select * from sto_holder_num where report_date>=?date order by sto_id asc, report_date desc", new string[]{"date"}, new object[]{startDate} ); IList<ShareholdersNumEntity> result = new List<ShareholdersNumEntity>(); if(ds!=null && ds.Tables.Count>0 && ds.Tables[0].Rows.Count>0){ foreach(DataRow row in ds.Tables[0].Rows){ result.Add(BuildEntity(row)); } } return result; }
/// <summary> /// 创建股东数数据。前提条件:<br /> /// 1. 每次调用,<paramref name="entities"/>只能包含同一只股票的股东数数据;<br /> /// 2. 调用时,必须确保StockId, PublishDate, HolderCount, AverageStockNumber, Source属性值有效; /// </summary> /// <param name="db"></param> /// <param name="entities"></param> public static int Create(Database db, IList<ShareholdersNumEntity> entities) { if(entities==null || entities.Count<=0) return 0; DateTime minDate = DateTime.MaxValue, effectiveDate = new DateTime(1990, 1, 1); int stockId = 0, exists=0, insertedRows = 0; try{ db.BeginTransaction(); //添加数据 foreach(ShareholdersNumEntity entity in entities){ //数据校验 if(entity.StockId<=0 || entity.ReportDate<=effectiveDate // || entity.HolderCount<=0 || entity.AverageStockNumber<=0 || (entity.Source==null || entity.Source.Trim().Length<=0)) throw new EntityException("[holder-num] [create] 属性无效,无法更新数据库,[id:" + entity.StockId + ", date:" + entity.ReportDate.ToString("yyyyMMdd")); if(stockId==0) stockId = entity.StockId; if(stockId!=entity.StockId) throw new EntityException("[holder-num] [create] entities中包含了多只股票的股东数数据"); entity.CreateTime = DateTime.Now; entity.VarNum = 0; //插入数据 exists = Convert.ToInt32(db.ExecScalar( "select count(*) from sto_holder_num where sto_id=?id and report_date=?date", new string[] {"id", "date"}, new object[] { entity.StockId, entity.ReportDate} )); if(exists<=0){ insertedRows += db.ExecNonQuery(INSERT_SQL, new string[]{"id", "date", "holdersNum", "varNum", "avgShares", "totalShares", "transShares", "time", "source"}, new object[]{entity.StockId, entity.ReportDate, entity.HoldersNum, entity.VarNum , entity.AvgShares, entity.TotalShares, entity.TransShares , entity.CreateTime, entity.Source}); if(minDate>entity.ReportDate) minDate = entity.ReportDate; } } //更新股东数增长量 int prevCount = 0; exists = Convert.ToInt32(db.ExecScalar( "select count(*) from sto_holder_num where sto_id=?id and report_date<?date", new string[] {"id", "date"}, new object[] { stockId, minDate} )); if(exists>0){ prevCount = Convert.ToInt32(db.ExecScalar( "select holders_num from sto_holder_num where sto_id=?id and report_date<?date order by report_date desc limit 1", new string[] {"id", "date"}, new object[] { stockId, minDate} )); } DataSet ds = db.ExecDataSet( "select * from sto_holder_num where sto_id=?id and report_date>=?date order by report_date asc", new string[] { "id", "date" }, new object[] { stockId, minDate } ); foreach(DataRow row in ds.Tables[0].Rows){ if(prevCount==0){ prevCount = Convert.ToInt32(row["holders_num"]); continue; } int curCount = Convert.ToInt32(row["holders_num"]); db.ExecNonQuery( "update sto_holder_num set var_num=?varNum where sto_id=?id and report_date=?date", new string[] { "id", "date", "varNum" }, new object[] { stockId, row["report_date"], curCount-prevCount} ); prevCount = curCount; } db.CommitTransaction(); }catch(Exception ex){ db.RollbackTransaction(); throw ex; } return insertedRows; }
/// <summary> /// 从文件导入分时交易数据 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> void BtnImpTradeListClick(object sender, EventArgs e) { Database db = new Database(this.txtDatabase.Text); db.Open(); ImportFileTimeShareTransaction.DoImportDirectory(db, this.txtTradeListDir.Text); db.Close(); }
public static void GenerateMALineChart(Database db, int stockId, DateTime start, DateTime end) { Stock stock = Stock.Get(db, stockId); IList<KJapaneseData> lk = KJapaneseData.Find(db, stockId, start, end); IDictionary<int, KTrendMALong> vertexes = new Dictionary<int, KTrendMALong>(); IList<KTrendMALong> lmal = KTrendMALong.FindAll(db, stockId); if (lmal.Count > 0){ vertexes.Add(int.Parse(lmal[0].StartDate.ToString("yyyyMMdd")), null); for (int i = 0; i < lmal.Count; i++){ int key = int.Parse(lmal[i].EndDate.ToString("yyyyMMdd")); if (!vertexes.ContainsKey(key)) vertexes.Add(key, lmal[i]); } } List<ChartKJapaneseJSON> json = new List<ChartKJapaneseJSON>(lk.Count); foreach (KJapaneseData k in lk){ ChartKJapaneseJSON jsonObj = new ChartKJapaneseJSON() { d = int.Parse(k.TxDate.ToString("yyyyMMdd")), nc = Convert.ToDecimal((KTrend.CalNetChange(k.PrevPrice, k.ClosePrice) * 100).ToString("f2")), o = k.OpenPrice, c = k.ClosePrice, hi = k.HighPrice, lo = k.LowPrice, vol = k.Volume, amt = k.Amount, er = stock.CirculatingCapital <= 0 ? 0 : Convert.ToDecimal((k.Volume * 1.0 / stock.CirculatingCapital * 100).ToString("f2")), ms = k.MAShort, ml = k.MALong, vs = k.VMAShort, vl = k.VMALong, vt = 0, vtr = 0, vts = 0, ds = 0 }; if (vertexes.ContainsKey(int.Parse(k.TxDate.ToString("yyyyMMdd")))){ KTrendMALong mal = vertexes[int.Parse(k.TxDate.ToString("yyyyMMdd"))]; if (mal != null){ jsonObj.vt = 1; jsonObj.ds = mal.TxDays; jsonObj.vtr = decimal.Parse((KTrend.CalNetChange(mal.StartValue, mal.EndValue) * 100).ToString("f1")); jsonObj.vts = mal.ChangeSpeed; } } json.Add(jsonObj); } string title = stock.StockCode + " " + stock.StockName + " (" + start.ToString("yyMMdd") + "-" + end.ToString("yyMMdd") + ")"; string jsonString = JsonConvert.SerializeObject(json, Formatting.Indented); string fileName = Directory.GetCurrentDirectory() + Path.DirectorySeparatorChar + "html" + Path.DirectorySeparatorChar + "chart-maline.json"; if (File.Exists(fileName)) File.Delete(fileName); File.CreateText(fileName).Close(); File.WriteAllText(fileName, "var title='" + title + "'; \n var klist = " + jsonString + ";", Encoding.GetEncoding("utf-8")); }
protected static DataSet FindAll(Database db, string tableName, int stockId) { return db.ExecDataSet( string.Format("select * from " + tableName + " where {0}=?stoid order by {1}", Mapper.StockId, Mapper.StartDate), new string[] { "stoid" }, new object[] { stockId } ); }
public static int BatchImport(Database db, List<KTrendMALong> entities) { return BatchImport(db, TABLE_NAME, entities); }
void BtnUpdateShareholdersNumClick(object sender, EventArgs e) { int startId = 1; int.TryParse(this.txtStartStockId.Text, out startId); Database db = new Database(this.txtDatabase.Text); db.Open(); IList<Stock> stocks = Stock.FindAll(db); db.Close(); while (startId > 1 && stocks.Count > 0 && stocks[0].StockId < startId){ stocks.RemoveAt(0); } ProgressStatus status = new ProgressStatus(); this._progressController.Start("抓取最新股东数", status); var tm = new MThreadManager<Stock>(THREAD_COUNT, typeof(ImpShareHoldersNumWorker), status); tm.SetContext("connection-string", this.txtDatabase.Text) .AddItem(stocks) .Start(); }
void BtnKTrendClick(object sender, EventArgs e) { Database db = new Database(this.txtDatabase.Text); db.Open(); IList<Stock> stocks = Stock.RemoveBlackList(Stock.FindAll(db)); db.Close(); ProgressStatus status = new ProgressStatus(); this._progressController.Start("计算K线趋势", status); var tm = new MThreadManager<Stock>(THREAD_COUNT, typeof(CalKTrendWorker), status); tm.SetContext("connection-string", this.txtDatabase.Text) .AddItem(stocks) .Start(); }
private bool Remove(Database db) { return db.ExecNonQuery( string.Format("delete from {0} where {1}=?id", Mapper.TableName, Mapper.Id), new string[] { "id" }, new object[] { this.Id } ) > 0; }
public static BulkInserter<KTrend> CreateBulkInserter(Database db, string tableName, int batchSize) { return new KTrendBulkInserter<KTrend>(db, tableName, batchSize); }
private bool UpdateMA(Database db) { return db.ExecNonQuery( string.Format("update {0} set {2}=?macs, {3}=?macl, {4}=?vmacs, {5}=?vmacl where {1}=?id" , Mapper.TableName, Mapper.Id, Mapper.MAShort, Mapper.MALong, Mapper.VMAShort, Mapper.VMALong), new string[] { "id", "macs", "macl", "vmacs", "vmacl" }, new object[] { this.Id, this.MAShort, this.MALong, this.VMAShort, this.VMALong } ) > 0; }
void BtnImpStockExtInfoClick(object sender, EventArgs e) { Database db = new Database(this.txtDatabase.Text); db.Open(); IList<Stock> stocks = Stock.FindAll(db); db.Close(); ProgressStatus status = new ProgressStatus(); this._progressController.Start("抓取股票基础信息", status); var tm = new MThreadManager<Stock>(THREAD_COUNT, typeof(ImpStockBasInfoWorker), status); tm.SetContext("connection-string", this.txtDatabase.Text) .AddItem(stocks) .Start(); }
void BtnImpPlateClick(object sender, EventArgs e) { if(this.txtPlateFile.Text.Trim().Length<=0) return; if(!File.Exists(this.txtPlateFile.Text)) return; string plate = (string)this.comboPlate.SelectedItem; if(String.IsNullOrEmpty(plate)) return; int plateId = 0; switch(plate){ case "上证50": plateId = 3; break; case "沪深300": plateId = 1; break; case "融资融券": plateId = 2; break; } if(plateId<=0) return; Database db = new Database(this.txtDatabase.Text); db.Open(); db.ExecNonQuery("delete from bas_plate_stocks where plate_id=?id" , new string[] { "id" }, new object[] { plateId }); using(StreamReader sr = new StreamReader(this.txtPlateFile.Text, Encoding.Default)){ string line = ""; while((line = sr.ReadLine()) != null){ if(string.IsNullOrEmpty(line)) continue; string[] fields = line.Trim().Split('\t'); if(fields.Length<2 || fields[0].Trim().Length!=6 || (fields[0].Trim()[0]!= '6' && fields[0].Trim()[0]!= '3' && fields[0].Trim()[0]!= '0')) continue; string code = fields[0].Trim(); int stockId = int.Parse(code); if(stockId<=0) continue; db.ExecNonQuery("insert into bas_plate_stocks(plate_id, sto_id) values(?pid, ?sid)" , new string[] {"pid", "sid"}, new object[] {plateId, stockId} ); } } db.Close(); MessageBox.Show("导入成功", "导入成功"); }
protected static int BatchImport(Database db, string tableName, IList entities) { if(entities == null || entities.Count<=0) return 0; int stockId = (entities[0] as KTrend).StockId; db.ExecNonQuery(string.Format("delete from {0} where {1}=?stoId", tableName, Mapper.StockId), new string[] { "stoId" }, new object[] { stockId }); BulkInserter<KTrend> bi = CreateBulkInserter(db, tableName, 200); //初步验证,一批次插入200条性能最好 for(int i=0; i<entities.Count; i++){ bi.Push(entities[i] as KTrend); } bi.Flush(); return entities.Count; }