【步步為營 Entity Framework+Reporting service開發】-(3) 創建commandline 應用程序 ,使用EF導入數據


接上一章,我們要創建一個commandline 應用程序,通過輸入參數,可以讓它去指定目錄讀取文件,並且導入數據庫

【設計】

在編寫這個程序之前,我們要想想這個程序都需要做什么?

1.讀取commandline 參數。一個目錄,taskid 和taskName 3個參數。

2.到指定目錄讀取csv/txt 文件,把csv/txt 轉成 DataTable (這里有兩種txt文件,trend 和bar)

3.去數據庫中查詢,如果當前taskid 沒有記錄則插入記錄。否則更新記錄。

 

根據上邊需要,我們需要創建如下類/方法:

 

 

 

 

 

 

點擊解決方案->Add new project->Console Application

命名為:ReportingSyncer。

proj 右鍵屬性,修改命名空間和程序集名稱,與前邊ReportingDBManager的前綴保持一致,即:CnBlogsDemos.ReportingSyncer

創建commandline 類:

View Code
namespace CnBlogsDemos.ReportingSyncer
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;


    public class CommandLine
    {
        protected Dictionary<string, string> _command;
        protected string _defaultConfig;

        public string InputDir
        {
            get
            {
                if (_command.ContainsKey("input"))
                {
                    return _command["input"];
                }
                throw new Exception("The expected parameter /input:[directory] is missing!");
            }
        }

        public string ConfigFilePath
        {
            get
            {
                if (_command.Keys.Contains("config"))
                {
                    return _command["config"];
                }
                return _defaultConfig;
            }
        }

        public string TaskID
        {
            get
            {
                if (_command.ContainsKey("taskid"))
                {
                    return _command["taskid"];
                }
                throw new Exception("The expected parameter /taskid:[id] is missing!");
            }

        }

        public string TaskName
        {
            get
            {
                if (_command.ContainsKey("taskname"))
                {
                    return _command["taskname"];
                }
                throw new Exception("The expected parameter /taskname:[name] is missing!");
            }

        }

        public CommandLine(string[] args)
        {
            ParseCommandLine(args);
            CheckMandatoryParameter();
        }

        public virtual string PrintInputParameters()
        {
            StringBuilder sb = new StringBuilder();
            sb.Append("Input Parameter:");
            foreach (KeyValuePair<string, string> param in _command)
            {
                sb.Append(string.Format("/{0}:{1}\t", param.Key, param.Value));
            }
            return sb.ToString();
        }

        private void ParseCommandLine(string[] args)
        {
            if (0 == args.Length ||
                (1 == args.Length &&
                (args[0].Contains("?") || args[0].ToLower().Contains("help"))))
            {
                Prompt();
                throw new ArgumentException("");
            }

            _command = new Dictionary<string, string>();
            try
            {
                foreach (string arg in args)
                {
                    string[] param = arg.ToLower().Split(new char[] { ':' }, 2);
                    _command.Add(param[0].Replace("/", ""), param[1]);
                }
            }
            catch (Exception e)
            {
                throw new ArgumentException(e.Message);
            }
        }

        protected virtual void CheckMandatoryParameter()
        {
            throw new NotImplementedException();
        }

        protected virtual void Prompt()
        {
            throw new NotImplementedException();
        }
    }
}

 

創建DataSyncer類(主要的操作都在這),先空着。

修改Programs類:

using System;
using CnBlogsDemos.ReportingSyncer;

namespace ReportingSyncer
{
    class Program
    {
        static int Main(string[] args)
        {
            int iRet = -1;
            try
            {
                CommandLine cmd = new CommandLine(args);
                DataSyncer ds = new DataSyncer(cmd);
            }
            catch (Exception e)
            {
                //TODO
            }
            return iRet;
        }
    }
}

現在我們開始寫DataSyncer類了。

首先添加EF引用。由於剛才我們在上一個proj 引用過了。我們可以去c:\users\你的名字\documents\visual studio 2010\Projects\ReportingSyncer\packages\EntityFramework.4.3.1\lib\net40\EntityFramework.dll找。我的是64位機器。32位的話,應該忽略(X86)。

再添加項目引用-》ReportingDBManager,這樣我們才可以使用剛才的DbStoreContext類。

 

根據上邊類圖所示:

DataSyncer類如下,具體的地方可以看代碼注釋:

namespace CnBlogsDemos.ReportingSyncer
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.IO;
    using System.Data;
    using CnBlogsDemos.ReportingDBManager;


    public class DataSyncer
    {
        private CommandLine _cmd;

        public DataSyncer(CommandLine cmd)
        {
            // TODO: Complete member initialization
            this._cmd = cmd;
        }

        internal int RunInCommandLineMode()
        {
            int iRet = -1;
            int taskId = 0;
            string inputDir = _cmd.InputDir;
            string taskName = string.Empty;
            string type = string.Empty;

            //Get taskid
            int.TryParse(_cmd.TaskID, out taskId);
            // if after parsing ,task id still equals 0 ,return
            if (taskId.Equals(0))
            {
                Console.WriteLine("taskid is invalid");
                return -1;
            }
            // if input directory is not exist parsing return
            if (!Directory.Exists(inputDir))
            {
                Console.WriteLine("input directory is not exist");
                return -1;
            }
            else
            {
                //read files from input dir
                var files = Directory.GetFiles(inputDir);

                if (!files.Any())
                {
                    Console.WriteLine("there is not files under input directory");
                    return -1;
                }
                else
                {
                    foreach (var file in files)
                    {
                        if (file.Contains("trend.txt"))
                        {
                            type = "trend";
                            InsertAnalysisData(file, taskId, taskName, type);
                        }
                        else if (file.Contains("bar.txt"))
                        {
                            type = "bar";
                            InsertAnalysisData(file, taskId, taskName, type);
                        }
                    }
                }


            }



            return iRet;

        }

        public void InsertAnalysisData(string filePath, int taskId, string taskName, string type)
        {
            if (File.Exists(filePath))
            {

                if (type.Equals("bar", StringComparison.OrdinalIgnoreCase))
                {
                    var dataRows = this.GetTableFromCSV(filePath).AsEnumerable();
                    // 創建一個新的 dbstore context 實例
                    using (DbStoreContext dsc = new DbStoreContext())
                    {
                        // 如果 Bars表 存在任何相同的TaskID,刪除相關記錄
                        if (dsc.Bars.Any(n => n.TaskID.Equals(taskId)))
                        {
                            foreach (var item in dsc.Bars.Where(n => n.TaskID.Equals(taskId)))
                            {
                                dsc.Bars.Remove(item);
                            }
                        }
                        
                        foreach (var row in dataRows)
                        {
                            // 注意 ,這個 row.Field<string>(index);中的index 對應我們csv/txt 文件中的數據列,索引從0開始
                            Bar b = new Bar();
                            b.KeyWord = row.Field<string>(0);
                            b.B1Better = Convert.ToInt32(row.Field<string>(1));
                            b.Equal = Convert.ToInt32(row.Field<string>(2));
                            b.B2Better = Convert.ToInt32(row.Field<string>(3));
                            b.Winner = row.Field<string>(4);
                            b.IsActive = true;
                            b.type = type;
                            b.TaskID = taskId;
                            b.TaskName = taskName;
                            dsc.Bars.Add(b);
                        }
                        //保存修改。EF會去執行插入數據到DB,默認開啟事務
                        dsc.SaveChanges();
                    }
                }
                else if (type.Equals("trend", StringComparison.OrdinalIgnoreCase))
                {
                    var tailWholePageTrendDataRows = this.GetTableFromCSV(filePath).AsEnumerable();
                    using (DbStoreContext dsc = new DbStoreContext())
                    {
                        if (dsc.Trends.Any(n => n.TaskID.Equals(taskId)))
                        {
                            foreach (var item in dsc.Trends.Where(n => n.TaskID.Equals(taskId)))
                            {
                                dsc.Trends.Remove(item);
                            }
                        }
                        foreach (var row in tailWholePageTrendDataRows)
                        {
                            // 注意 ,這個 row.Field<string>(index);中的index 對應我們csv/txt 文件中的數據列,索引從0開始
                            Trend t = new Trend();
                            t.id = Convert.ToInt32(row.Field<string>(0));
                            t.TaskID = taskId;
                            t.Time = Convert.ToDateTime(row.Field<string>(3));
                            t.B1Better = Convert.ToInt32(row.Field<string>(4));
                            t.Equal = Convert.ToInt32(row.Field<string>(5));
                            t.B2Better = Convert.ToInt32(row.Field<string>(6));
                            t.UnCertain = Convert.ToInt32(row.Field<string>(7));
                            t.GrandTotal = Convert.ToInt32(row.Field<string>(8));
                            t.TaskName = taskName;
                            t.IsActive = true;
                            t.type = type;
                            dsc.Trends.Add(t);
                        }
                        dsc.SaveChanges();
                    }

                }

            }
        }

        /// <summary>
        /// GetTableFromCSV file
        /// </summary>
        /// <param name="csvFilePath">file path</param>
        /// <returns>data table</returns>
        private  DataTable GetTableFromCSV(string csvFilePath)
        {
            using (StreamReader sr = new StreamReader(csvFilePath))
            {
                string line = sr.ReadLine();
                if (!string.IsNullOrEmpty(line))
                {
                    string[] columns = line.Split('\t');
                    DataTable dt = new DataTable();
                    foreach (string columnName in columns)
                    {
                        dt.Columns.Add(columnName);
                    }

                    while ((line = sr.ReadLine()) != null)
                    {
                        DataRow dr = dt.NewRow();
                        string[] dataColumns = line.Split('\t');
                        dt.Rows.Add(dataColumns);
                    }
                    return dt;
                }
                throw new Exception(string.Format("File Content in {0} is empty", csvFilePath));
            }
        }
    }
}

 

倒數第二步:創建app.config。上篇文章說過。我們刪除了ReportingDBManager類庫中的app.config。

我們要在ReportingSyncer 類庫中添加一個app.config指定我們的連接字符串

 

<?xml version="1.0" encoding="utf-8"?>
<configuration>
<connectionStrings>
<add name="ReportingDataBase"
connectionString="Initial Catalog=DemoReportDB;data source=.;Integrated Security=SSPI;Trusted_Connection=Yes" providerName="System.Data.SqlClient" />
</connectionStrings>
</configuration>

 

 

 

 

最后一步,創建測試數據。

讓我們創建一個文件夾E:\demos\reportingImprot。下邊包含2個txt文件:trend.txt 和 bar.txt

trend.txt:

id taskid taskname time b1 equal b2 uncertain grandtotal 0 1 task1 2012-6-27 200 300 280 220 1000

注意中間是tab分割。

bar.txt:

KeyWord B1Better Equal B2Better Winner 聯眾 2 0 3 B1 瘋狂倒計時 0 0 3 B2 張娜拉 0 1 2 B1 截圖軟件 1 0 1 B2

 

因為有漢字,請保存為unicode格式

為了方便模擬用戶輸入,我們可以預設commandline 參數:

右擊ReportingSyncer 項目屬性:debug-》Commandline arguments 輸入:/input:E:\demos\reportingImprot/taskid:5 /taskname:TestTask。

在實際使用時候可以用cmd找到你的bin目錄 執行release /debug 下的 exe文件。

例如 cmd-> c:

           ->cd e:\C:\Users\ricky\Documents\Visual Studio 2010\Projects\ReportingSyncer\ReportingSyncer\bin\Release reportingsyncer /input:E:\demos\reportingImprot/taskid:5 /taskname:TestTask

我們還是在debug 下試試吧。運行,也可以調試看看。

檢查本地數據庫。太神奇了吧?數據已經導進來了。

 

檢查一下表結構

 

好,這章就講到這里。

下一章會繼續介紹如何使用vs 創建report

 

源代碼下載


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM