IronPython ActiveRecord In Action: 如此簡單

來源:互聯網
上載者:User

ROR ActiveRecord從概念上來說是目前最為理想的ORM,因為只要按照預設的規則,它完全不需要程式員維護任何實體屬性和對應檔,這是動態語言強大的運行期特性的體現。但是在.Net平台上,IronRuby目前還遠遠沒有達到可用的地步。那麼用比較成熟的IronPython能否達到類似的效果呢?我做了個實驗,結果發現確實是可行的。更加美妙的是,動態構造的屬性不但能夠在Python代碼中直接使用,而且也能夠通過反射擷取,從而映射到ASP.NET頁面也不需要任何額外的工作。

 

下面就是例子。我們可以在頁面的Code Behind代碼中訪問python代碼:

        protected void Page_Load(object sender, EventArgs e)
        {
            if (!IsPostBack)
            {
                grid.DataSource = RunPythonFunction("User", "query");
                grid2.DataSource = RunPythonFunction("Corp", "query");
                DataBind();
            }
        }

        private object RunPythonFunction(string className, string funcName)
        {
            if (_engine == null)
                _engine = Python.CreateEngine();

            if (_code == null)
            {
                string fileName = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "db.py");
                var source = _engine.CreateScriptSourceFromFile(fileName, Encoding.Default, SourceCodeKind.Statements);
                _code = source.Compile();
            }

            var scope = _engine.CreateScope();
            _code.Execute(scope);

            var klass = scope.GetVariable(className);
            var func = _engine.Operations.GetMember<Func<object>>(klass, funcName);
            return func();
        }

 

對應的 IronPython指令碼如下:

class ActiveRecord(object):
    @classmethod
    def getTableName(cls):
        return cls.__name__ + 's'
        
    @classmethod
    def query(cls):
        sql = 'select * from %s' % cls.getTableName()
        result = []
        
        conn = SqlConnection(connStr)
        try:
            conn.Open()
            cmd = SqlCommand(sql, conn)
            reader = cmd.ExecuteReader()
            fields = [reader.GetName(i) for i in range(reader.FieldCount)]
            while reader.Read():
                record = cls()
                for index, field in enumerate(fields):
                    setattr(record, field, reader[index])
                result.append(record)
            reader.Close()
            cmd.Dispose()
            return result        
        finally:
            conn.Close()
        

class User(ActiveRecord):
    pass

class Corp(ActiveRecord):
    pass

 

 這麼簡單的幾行代碼就完成了從資料庫記錄到實體的映射。子類不再需要什麼設定檔,資料庫有哪些欄位,實體就自動產生了哪些屬性。

query()方法返回的是一個集合類型,設定到GridView.DataSource就可以直接映射到頁面控制項,和C#手工編寫實體效果完全一樣:

 

 

 

後記:我自己曾經用幾千行C#代碼實現了一個基本的ORM架構,但是現在,我發現同樣的功能用Python只要幾百行代碼就能實現,而且用起來更加簡單。這實在是很讓我有一種把以前的代碼全部扔掉,用IronPython重寫的衝動。唯一不爽的地方是Visual Studio不允許我用Python來寫ASP頁面(IronPython for ASP.NET那個CTP一點也不好用),因此還是不得不寫很多stub代碼在C#和Python之間來迴轉換。雖然微軟聲稱自己在DLR平台的發展上超過Java,但是這未免有點口惠而實不至的味道,因為IDE基本上沒有任何支援。而Java世界不論Eclipse還是Netbeans都對多種主流動態語言提供了相當完整的支援,這種情況什麼時候才能改變呢?

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.