LLBL Gen Pro 设计器使用指南
LLBL Gen Pro是個專業(yè)的ORM開發(fā)工具,官方網(wǎng)站是 http://www.llblgen.com/
LLBL Gen Pro是個支持多種持久層框架的ORM工具,如LLBL Gen Pro Runtime、Entity Framework、NHibernate和LINQ to SQL。其他一些新特性還有:
支持.NET 4.0、模型先行或數(shù)據(jù)庫先行的開發(fā)模式、模型視圖、項(xiàng)目驗(yàn)證。LLBL Gen Pro有兩個主要的組件:一是設(shè)計器,
這是一個可視化工具,供開發(fā)者創(chuàng)建項(xiàng)目所用;二是運(yùn)行時,這是與數(shù)據(jù)庫交互的持久層框架,用于執(zhí)行映射操作。
1 設(shè)計實(shí)體類型
打開LLBL Gen程序,選擇創(chuàng)建新項(xiàng)目
打開Catelog Explorer,選擇從數(shù)據(jù)庫添加關(guān)系對象模型
輸入SQL Server實(shí)例名稱,登陸用戶和秘密,點(diǎn)”Test Connection”測試連接
測試連接成功后,點(diǎn)擊Next按鈕,進(jìn)行到下一步,選擇數(shù)據(jù)庫表
如果需要支持存儲過程調(diào)用,可選擇勾選存儲過程
LLBL Gen開始讀取系統(tǒng)表信息,供生成實(shí)體定義。
在Catelog Explorer點(diǎn)選右鍵,選擇從表定義中生成實(shí)體
如果表名帶有簡寫,可以輸入一個有意義容易理解的實(shí)體名稱
LLBL Gen不建議的命名方法
1. 在表名前加前綴。比如給客戶表名定義成tblCustomer, 用戶表定義成tblUser,只要是表都加一個tbl標(biāo)簽。如果是手寫SQL語句,這可以區(qū)分出表和自定義的實(shí)體,但是ORM會對每個生成的實(shí)體名稱后面加Entity,比如Employee表,默認(rèn)會對生EmployeeEntity。
為此,LLBL Gen設(shè)計了名稱剔除(strip)模式,請看下圖中的配置屬性
2. 同樣的原理,存儲過程也不應(yīng)該加sp_前綴,視圖也不應(yīng)該加vw_。
2 修改實(shí)體屬性
在Project Exploer窗口中,選擇要修改的實(shí)體名,點(diǎn)擊編輯
默認(rèn)情況下,不需要做修改,LLBL Gen會生成合適的數(shù)據(jù)庫與實(shí)體映射。但是有以下幾種情況需要修改。
2.1 空值類型
數(shù)據(jù)庫字段值允許為空,對應(yīng)生成的代碼類型應(yīng)該是NULLABLE,通常看到的可空類型。
生成的代碼例子
/// <summary> The CreatedDate property of the Entity User<br/><br/>///Mapped on table field: User.CreatedDate</summary>/// <remarks>Mapped on table field: "User"."CreatedDate"<br/>/// Table field type characteristics (type, precision, scale, length): DateTime, 0, 0, 0<br/>/// Table field behavior characteristics (is nullable, is PK, is identity): true, false, false</remarks>public virtual Nullable<System.DateTime> CreatedDate{get { return (Nullable<System.DateTime>)GetValue((int)UserFieldIndex.CreatedDate, false); }set { SetValue((int)UserFieldIndex.CreatedDate, value); }}如果不想生成這種類型,可在Field mapping窗口中,選擇對應(yīng)的屬性名稱,去掉Is nullable標(biāo)簽。
再次生成代碼,它生成的屬性應(yīng)該是這樣的
/// <summary> The CreatedDate property of the Entity User<br/><br/>///Mapped on table field: User.CreatedDate</summary>/// <remarks>Mapped on table field: "User"."CreatedDate"<br/>/// Table field type characteristics (type, precision, scale, length): DateTime, 0, 0, 0<br/>/// Table field behavior characteristics (is nullable, is PK, is identity): true, false, false</remarks>public virtual System.DateTime CreatedDate{get { return (Nullable<System.DateTime>)GetValue((int)UserFieldIndex.CreatedDate, false); }set { SetValue((int)UserFieldIndex.CreatedDate, value); }}2.2 自定義屬性
LLBL Gen支持為實(shí)體增加自定義屬性,獨(dú)立于數(shù)據(jù)庫字段映射之外的屬性,相當(dāng)于代碼生成器。
在生成代碼中,會產(chǎn)生額外的屬性,它的類型是Dictionary
private static void SetupCustomPropertyHashtables(){_customProperties = new Dictionary<string, string>();_fieldsCustomProperties = new Dictionary<string, Dictionary<string, string>>();Dictionary<string, string> fieldHashtable;_fieldsCustomProperties.Add("UserName", fieldHashtable);fieldHashtable = new Dictionary<string, string>();fieldHashtable.Add("AllowEditForNewOnly", @"");}在運(yùn)行時,可通過下面的方法,找到自定義屬性
// [C#]Dictionary<string, string> userProperties = UserEntity.CustomProperties;string description = userProperties ["AllowEditForNewOnly "];2.3 類型轉(zhuǎn)化器
如果需要對值進(jìn)行類型轉(zhuǎn)化。比如數(shù)據(jù)庫中存儲的是字符串,但要在程序中以bool類型來使用,可設(shè)置TypeConverter to use
強(qiáng)類型編程的好處是可以發(fā)現(xiàn)編譯時錯誤,而不是到運(yùn)行才出現(xiàn)錯誤。
舉例說明,我們常用1或0表示銷售單已經(jīng)過帳或沒有過帳,但是在程序中以1或0來設(shè)置,缺少編譯期間的檢查,即使你賦值時給它值3,也不會有編譯錯誤。如果換成bool類型,true表是已經(jīng)過帳,false表示沒有過帳,則可以極大的增加可維護(hù)性。
請參考如下的代碼,了解類型轉(zhuǎn)換器,進(jìn)一步的原理請參考.NET組件設(shè)計。
Namespace TypeConverters {[Description("Converter with as core type System.Boolean, for mapping a field with a .NET type System.Boolean onto a string database field")]public class BooleanStringConverter : TypeConverter{/// <summary>/// Initializes a new instance of the <see cref="BooleanStringConverter"/> class./// </summary>public BooleanStringConverter(){}/// <summary>/// Returns whether this converter can convert an object of the given type to the type of this converter (Boolean)./// </summary>/// <param name="context">Ignored</param>/// <param name="sourceType">A <see cref="T:System.Type"/> that represents the type you want to convert from.</param>/// <returns>/// <see langword="true "/>if this converter can perform the conversion; otherwise, <see langword="false"/>./// </returns>/// <remarks>Accepted types are: String</remarks>public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType){// any integer type is accepted. No fractional types like float/double.switch (sourceType.FullName){case "System.String":return true;default:return false;}}/// <summary>/// Returns whether this converter can convert the object to the specified type./// </summary>/// <param name="context">Ignored</param>/// <param name="destinationType">A <see cref="T:System.Type"/> that represents the type you want to convert to.</param>/// <returns>/// <see langword="true "/>if this converter can perform the conversion; otherwise, <see langword="false"/>./// </returns>/// <remarks>Accepted types are: String. True will be converted to 1, false will be/// converted to 0.</remarks>public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType){// any integer type is accepted. No fractional types like float/double.switch (destinationType.FullName){case "System.String":return true;default:return false;}}/// <summary>/// Converts the given object to the type of this converter (Boolean)./// </summary>/// <param name="context">Ignored</param>/// <param name="culture">Ignored</param>/// <param name="value">The <see cref="T:System.Object"/> to convert.</param>/// <returns>/// An <see cref="T:System.Object"/> that represents the converted value, which is of type boolean./// </returns>/// <exception cref="T:System.NotSupportedException">The conversion could not be performed.</exception>public override object ConvertFrom(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value){bool toReturn = true;switch (value.GetType().FullName){case "System.String":toReturn = ((string)value == "Y");break;case "System.DBNull":toReturn = false;break;default:throw new NotSupportedException("Conversion from a value of type '" + value.GetType().ToString() + "' to System.Boolean isn't supported");}return toReturn;}/// <summary>/// Converts the given value object to the specified type/// </summary>/// <param name="context">Ignored</param>/// <param name="culture">Ignored</param>/// <param name="value">The <see cref="T:System.Object"/> to convert.</param>/// <param name="destinationType">The <see cref="T:System.Type"/> to convert the <paramref name="value"/> parameter to.</param>/// <returns>/// An <see cref="T:System.Object"/> that represents the converted value. The value will be 1 if <paramref name="value"/> is true, otherwise 0/// </returns>/// <exception cref="T:System.ArgumentNullException">The <paramref name="destinationType"/> parameter is <see langword="null"/>.</exception>/// <exception cref="T:System.NotSupportedException">The conversion could not be performed.</exception>public override object ConvertTo(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value, Type destinationType){if (value == null){throw new ArgumentNullException("value", "Value can't be null");}if (!(value is bool)){throw new ArgumentException("Value isn't of type boolean", "value");}if ((bool)value){switch (destinationType.FullName){case "System.String":return (string)"Y";case "System.DBNull":return (string)"N";default:throw new NotSupportedException("Conversion to a value of type '" + destinationType.ToString() + "' isn't supported");}}else{switch (destinationType.FullName){case "System.String":case "System.DBNull":return (string)"N";default:throw new NotSupportedException("Conversion to a value of type '" + destinationType.ToString() + "' isn't supported");}}}/// <summary>/// Creates an instance of the Type that this <see cref="T:System.ComponentModel.TypeConverter"/> is associated with (bool)/// </summary>/// <param name="context">ignored.</param>/// <param name="propertyValues">ignored.</param>/// <returns>/// An <see cref="T:System.Object"/> of type bool. It always returns 'true' for this converter./// </returns>public override object CreateInstance(ITypeDescriptorContext context, System.Collections.IDictionary propertyValues){return true;}} }3 生成源代碼
設(shè)置好屬性后,可用生成源代碼,F7調(diào)出生成窗口
Template group中Adapter 模式把數(shù)據(jù)和數(shù)據(jù)的讀寫?yīng)毩⒊啥€部分,SelfServicing則混合兩者
Adapter模式下,讀取用戶的代碼,如下所示
UserLogEntity _UserLog = new UserLogEntity(Logno);using (DataAccessAdapterBase adapter = GetSystemDataAccessAdapter()){bool found = adapter.FetchEntity(_UserLog, prefetchPath, null, fieldList);if (!found) throw new RecordNotFoundException("Invalid UserLog");}SelfServicing模式,則是這樣的
CustomerEntity customer = new CustomerEntity();customer.FetchUsingPK("CHOPS");實(shí)際過程中,生成器生成的代碼和自己加入的業(yè)務(wù)邏輯分開存放,當(dāng)數(shù)據(jù)庫更新字段時,再次生成代碼,為了不覆蓋已經(jīng)加入的代碼,常常要把自己的邏輯放到代碼生成器生成的代碼之外。
在我的項(xiàng)目中,我是將Database Generic和Database Specific兩個項(xiàng)目的代碼放在一起,在同一個項(xiàng)目中進(jìn)行編譯。
框架中大量依賴于這個設(shè)置,對生成的實(shí)體代碼進(jìn)行反射,讀取元數(shù)據(jù)。
?
4 MySQL 快速開發(fā)
4.1 MySQL 安裝配置
安裝MySQL, 使用查詢分析器連接數(shù)據(jù)庫服務(wù)器
創(chuàng)建數(shù)據(jù)庫CTU, 并且創(chuàng)建新表Agent
給數(shù)據(jù)表Agent添加三筆數(shù)據(jù),Jack,Tony,Charles
數(shù)據(jù)庫設(shè)計的任務(wù)到此為止,記得給每個表添加主鍵。這里設(shè)置的主鍵是Name
4.2 LLBL Gen 設(shè)計實(shí)體模型
啟動LLBL Gen 3.1, 創(chuàng)建新的項(xiàng)目,注意選擇Target為LLBL Gen框架
在Category Explorer窗口中,右鍵,添加新連接
請在context菜單中選擇Reverse-engineer Tables to Entity Definitions
這些表就會自動mapping到實(shí)體集合中
從圖中可以看到,已經(jīng)發(fā)現(xiàn)了Agent表
如果需要進(jìn)一步的編輯屬性與字段的映射關(guān)系,請用Edit 菜單,打開窗體
在這里,可以設(shè)置關(guān)系,設(shè)置映射的名稱。
F7,可以開始生成代碼
默認(rèn)情況下,會生成2個項(xiàng)目文件
從名稱中可以看出,一個是數(shù)據(jù)庫無關(guān)的,另一個是做數(shù)據(jù)訪問的。以此的原理是我們在生成數(shù)據(jù)庫時,選擇Adapter模式,而不是SelfServicing模式.
4.3 啟動程序
在Visual Studio中打開生成的代碼,并且添加測試項(xiàng)目(Console)
解決方案瀏覽器中現(xiàn)在有三個項(xiàng)目Main是我們用來測試數(shù)據(jù)訪問的
再來看一下Main方法,只有簡單的幾行程序,也就是一個最簡單的測試程序
UserEntity user=new UserEntity("Jack") DataAccessAdapter adapter=new DataAccessAdapter(); adapter.FetchEntity(user); string title=user.Description;它會生成SQL語句 SELECT Name , Postion , Description FROM agent
?
LLBL Gen支持NHibernate,ADO.NET Entity Framework,可以考慮用它來作為ORM框架,實(shí)現(xiàn)三層架構(gòu)中的數(shù)據(jù)訪問層。
轉(zhuǎn)載于:https://www.cnblogs.com/JamesLi2015/archive/2013/05/15/3079230.html
總結(jié)
以上是生活随笔為你收集整理的LLBL Gen Pro 设计器使用指南的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 使用c#类库绘制柱状图
- 下一篇: android源码查看源码的版本