您的位置:首页 > 其它

LLBL Gen + Entity Framework 程序设计入门

2013-07-22 20:42 232 查看
EntityFramework推出有好几年,除了微软的VisualStudio可以做实体框架开发外,第三方的开发工具如LLBLGen,
DevartEntityDeveloper也可以用来做设计开发。
设计数据库表Configuration,它的SQL定义如下
IFOBJECT_ID('dbo.Configuration')ISNOTNULL
DROPTABLEdbo.Configuration
GO

CREATETABLEdbo.Configuration
(
RecnumINTIDENTITYNOTNULL,
MasterKeyNVARCHAR(50)NOTNULL,
DescriptionTEXTNULL,
RemarkNVARCHAR(400)NULL,
CONSTRAINTPK_X_ConfigPRIMARYKEY(MasterKey)
)
GO
.csharpcode,.csharpcodepre
{
font-size:small;
color:black;
font-family:consolas,"CourierNew",courier,monospace;
background-color:#ffffff;
/*white-space:pre;*/
}
.csharpcodepre{margin:0em;}
.csharpcode.rem{color:#008000;}
.csharpcode.kwrd{color:#0000ff;}
.csharpcode.str{color:#006080;}
.csharpcode.op{color:#0000c0;}
.csharpcode.preproc{color:#cc6633;}
.csharpcode.asp{background-color:#ffff00;}
.csharpcode.html{color:#800000;}
.csharpcode.attr{color:#ff0000;}
.csharpcode.alt
{
background-color:#f4f4f4;
width:100%;
margin:0em;
}
.csharpcode.lnum{color:#606060;}打开LLBLGen,创建一个新项目,选择EntityFrameworkv1



这里还有其它版本的EntityFramework。对应关系如下
EntityFrameworkv1=>EntityFramework3.5SP1
EntityFrameworkv4=>EntityFramework4/4.5
再到CategoryExplorer窗口中,选择添加数据库映射,选择数据库类型,设置连接参数



生成实体模型,继续在CategoryExplorer窗口中,把表添加到当前项目的实体中,如下图所示



验证实体类型,准备生成代码,但是出现以下几个错误:
TheEntity"FileType"containsfield"FileType"whichhasthesamenameasitscontainingelement,somethingwhichisn'tsupportedbytheEntityFramework
.csharpcode,.csharpcodepre
{
font-size:small;
color:black;
font-family:consolas,"CourierNew",courier,monospace;
background-color:#ffffff;
/*white-space:pre;*/
}
.csharpcodepre{margin:0em;}
.csharpcode.rem{color:#008000;}
.csharpcode.kwrd{color:#0000ff;}
.csharpcode.str{color:#006080;}
.csharpcode.op{color:#0000c0;}
.csharpcode.preproc{color:#cc6633;}
.csharpcode.asp{background-color:#ffff00;}
.csharpcode.html{color:#800000;}
.csharpcode.attr{color:#ff0000;}
.csharpcode.alt
{
background-color:#f4f4f4;
width:100%;
margin:0em;
}
.csharpcode.lnum{color:#606060;}.csharpcode,.csharpcodepre
{
font-size:small;
color:black;
font-family:consolas,"CourierNew",courier,monospace;
background-color:#ffffff;
/*white-space:pre;*/
}
.csharpcodepre{margin:0em;}
.csharpcode.rem{color:#008000;}
.csharpcode.kwrd{color:#0000ff;}
.csharpcode.str{color:#006080;}
.csharpcode.op{color:#0000c0;}
.csharpcode.preproc{color:#cc6633;}
.csharpcode.asp{background-color:#ffff00;}
.csharpcode.html{color:#800000;}
.csharpcode.attr{color:#ff0000;}
.csharpcode.alt
{
background-color:#f4f4f4;
width:100%;
margin:0em;
}
.csharpcode.lnum{color:#606060;}映射的实体名字段中,不能包含与实体名称一样的字段。比如,我有一个FileType的表,映射到FileType实体,它包含一个FileType的主键字段,自动生成映射时,这是不允许的。
清除这个错误之后,按F7生成代码,用VisualStudio2012打开项目,如下图所示



LLBLGen代码生成器帮忙我们生成EntityFramework所需要的edmx文件,类型定义和DataContext类型。
来看一下生成的类型定义代码,Configuration表映射的实体类型Configuration实体,它的代码如下
///<summary>Classwhichrepresentstheentity'Configuration'.</summary>
[Serializable]
[DataContract(IsReference=true)]
[EdmEntityType(NamespaceName="Entity35Model",Name="Configuration")]
publicpartialclassConfiguration:CommonEntityBase
{
#regionClassMemberDeclarations
privateSystem.String_description;
privateSystem.String_masterKey;
privateSystem.Int32_recnum;
privateSystem.String_remark;
#endregion

#regionExtensibilityMethodDefinitions
partialvoidOnDescriptionChanging(System.Stringvalue);
partialvoidOnDescriptionChanged();
partialvoidOnMasterKeyChanging(System.Stringvalue);
partialvoidOnMasterKeyChanged();
partialvoidOnRecnumChanging(System.Int32value);
partialvoidOnRecnumChanged();
partialvoidOnRemarkChanging(System.Stringvalue);
partialvoidOnRemarkChanged();
#endregion

///<summary>Initializesanewinstanceofthe<seecref="Configuration"/>class.</summary>
publicConfiguration():base()
{
}

///<summary>Factorymethodtocreateanewinstanceoftheentitytype'Configuration'</summary>
///<paramname="masterKeyValue">Theinitialvalueforthefield'MasterKey'</param>
///<paramname="recnumValue">Theinitialvalueforthefield'Recnum'</param>
publicstaticConfigurationCreateConfiguration(System.StringmasterKeyValue,System.Int32recnumValue)
{
vartoReturn=newConfiguration();
toReturn.MasterKey=masterKeyValue;
toReturn.Recnum=recnumValue;
returntoReturn;
}

#regionClassPropertyDeclarations
///<summary>GetsorsetstheDescriptionfield.</summary>
[DataMember]
[EdmScalarProperty()]
publicSystem.StringDescription
{
get{return_description;}
set
{
OnDescriptionChanging(value);
this.ReportPropertyChanging("Description");
_description=SetValidValue(value,true);
this.ReportPropertyChanged("Description");
OnDescriptionChanged();
}
}

///<summary>GetsorsetstheMasterKeyfield.</summary>
[DataMember]
[EdmScalarProperty(EntityKeyProperty=true,IsNullable=false)]
publicSystem.StringMasterKey
{
get{return_masterKey;}
set
{
if(_masterKey==value)
{
return;
}
OnMasterKeyChanging(value);
this.ReportPropertyChanging("MasterKey");
_masterKey=SetValidValue(value,false);
this.ReportPropertyChanged("MasterKey");
OnMasterKeyChanged();
}
}

///<summary>GetsorsetstheRecnumfield.</summary>
[DataMember]
[EdmScalarProperty(IsNullable=false)]
publicSystem.Int32Recnum
{
get{return_recnum;}
privateset
{
OnRecnumChanging(value);
this.ReportPropertyChanging("Recnum");
_recnum=SetValidValue(value);
this.ReportPropertyChanged("Recnum");
OnRecnumChanged();
}
}

///<summary>GetsorsetstheRemarkfield.</summary>
[DataMember]
[EdmScalarProperty()]
publicSystem.StringRemark
{
get{return_remark;}
set
{
OnRemarkChanging(value);
this.ReportPropertyChanging("Remark");
_remark=SetValidValue(value,true);
this.ReportPropertyChanged("Remark");
OnRemarkChanged();
}
}

#endregion
}
LLBLGen让生成的实体类型派生于CommonEntityBase,这个类型派生于EntityObject,定义如下
///<summary>Classwhichisthecommonbaseclassforallgeneratedentityclasses.</summary>
///<remarks>Asallnon-subtypeentityclassesderivefromthisclass,useapartialclassofthisclasstoimplementcodewhichissharedamongallgeneratedentityclasses</remarks>
[DataContract(IsReference=true)]
[Serializable]
publicabstractpartialclassCommonEntityBase:EntityObject
{
#regionClassExtensibilityMethods
///<summary>Methodcalledfromtheconstructor</summary>
partialvoidOnCreated();
#endregion

///<summary>Initializesanewinstanceofthe<seecref="CommonEntityBase"/>class.</summary>
protectedCommonEntityBase():base()
{
OnCreated();
}

}
可以在这个类型中,创建一些公共的方法以方便在生成的实体类型中使用。
LLBLGen为实体框架的实体的每个属性添加了二个跟踪机制方法:Changing和Changed方法。这里可以写我们实体的业务逻辑。比如在采购单中,用户改变单价时,自动重新计算金额(金额=数量*单价)。
以备注属性为例子,请看下面的代码

///<summary>GetsorsetstheRemarkfield.</summary>
[DataMember]
[EdmScalarProperty()]
publicSystem.StringRemark
{
get{return_remark;}
set
{
OnRemarkChanging(value);
this.ReportPropertyChanging("Remark");
_remark=SetValidValue(value,true);
this.ReportPropertyChanged("Remark");
OnRemarkChanged();
}
}
.csharpcode,.csharpcodepre
{
font-size:small;
color:black;
font-family:consolas,"CourierNew",courier,monospace;
background-color:#ffffff;
/*white-space:pre;*/
}
.csharpcodepre{margin:0em;}
.csharpcode.rem{color:#008000;}
.csharpcode.kwrd{color:#0000ff;}
.csharpcode.str{color:#006080;}
.csharpcode.op{color:#0000c0;}
.csharpcode.preproc{color:#cc6633;}
.csharpcode.asp{background-color:#ffff00;}
.csharpcode.html{color:#800000;}
.csharpcode.attr{color:#ff0000;}
.csharpcode.alt
{
background-color:#f4f4f4;
width:100%;
margin:0em;
}
.csharpcode.lnum{color:#606060;}
partialvoidOnRemarkChanging(System.Stringvalue);
partialvoidOnRemarkChanged();
这二个方法都是partial方法,如果我们没有定义方法体,则编译时,它会被忽略。partial方法是C#3.0才引入的特性,为方便代码生成器与开发人员之间的合作更紧密。试想一下,怎么在不修改代码生成器生成的方法的情况下,添加自定义的业务代码到类型的方法,属性中去呢?答案是partial方法。
同时,因为生成的实体类型已经加了partial关键字,所以我们可以再加入一个同名的实体类型,用来写业务逻辑,而不更改代码生成器自动生成的代码。
最后,写一个测试方法,让它读取系统的配置表Configuration中的数据:
publicstaticvoidMain(string[]args)
{
Entity35DataContextentity35DataContext=newEntity35DataContext();
varconfigurations=fromiteminentity35DataContext.Configurations
selectitem;

foreach(vardbDataRecordinconfigurations)
{
stringcompanyCode=dbDataRecord.MasterKey;

}
}
一行代码即可完成数据库的读取,而且读取的数据是强类型,非常方便。
一般在入门例子中,容易出错的地方是配置文件的内容,来看一下App.config文件的内容:
<?xmlversion="1.0"encoding="utf-8"?>
<configuration>
<connectionStrings>
<!--pleaseadjusttheconnectionstringembeddedintheelementbelowtotargetthepropercatalog/serverusingtheproperuser/passwordcombination-->
<addname="ConnectionString.SQLServer(SqlClient)"connectionString="metadata=res://*/Entity35.csdl|res://*/Entity35.ssdl|res://*/Entity35.msl;provider=System.Data.SqlClient;providerconnectionstring="datasource=.\sqlexpress;initialcatalog=Framework;integratedsecurity=SSPI;persistsecurityinfo=False;packetsize=4096""providerName="System.Data.EntityClient"/>
</connectionStrings>
</configuration>
.csharpcode,.csharpcodepre
{
font-size:small;
color:black;
font-family:consolas,"CourierNew",courier,monospace;
background-color:#ffffff;
/*white-space:pre;*/
}
.csharpcodepre{margin:0em;}
.csharpcode.rem{color:#008000;}
.csharpcode.kwrd{color:#0000ff;}
.csharpcode.str{color:#006080;}
.csharpcode.op{color:#0000c0;}
.csharpcode.preproc{color:#cc6633;}
.csharpcode.asp{background-color:#ffff00;}
.csharpcode.html{color:#800000;}
.csharpcode.attr{color:#ff0000;}
.csharpcode.alt
{
background-color:#f4f4f4;
width:100%;
margin:0em;
}
.csharpcode.lnum{color:#606060;}这里是设置连接字符串的地方,从生成的ObjectContext类型中,可以看到不带参数的构造方法为从这里读取连接字符串,它的其它的几个方法,如下代码所示
///<summary>Initializesanewinstanceofthe<seecref="Entity35DataContext"/>classusingtheconnectionstringfoundinthe'Entity35'sectionoftheapplicationconfigurationfile.</summary>
publicEntity35DataContext():base("name=ConnectionString.SQLServer(SqlClient)","Entity35Entities")
{
Initialize();
}

///<summary>Initializesanewinstanceofthe<seecref="Entity35DataContext"/>class</summary>
publicEntity35DataContext(stringconnectionString):base(connectionString,"Entity35Entities")
{
Initialize();
}

///<summary>Initializesanewinstanceofthe<seecref="Entity35DataContext"/>class</summary>
///<paramname="connection">ReadytouseEntityConnectionobjecttobeusedwiththiscontext</param>
publicEntity35DataContext(System.Data.EntityClient.EntityConnectionconnection):base(connection,"Entity35Entities")
{
Initialize();
}
EntityFramework的连接字符串与经常写的SQLServer的SqlConnection的字符串有所区别,要指定依据edmx生成的三个文件的位置,因为edmx文件的BuildAction为EntityDeploy,所以它会被嵌入到生成的程序集中。



.csharpcode,.csharpcodepre
{
font-size:small;
color:black;
font-family:consolas,"CourierNew",courier,monospace;
background-color:#ffffff;
/*white-space:pre;*/
}
.csharpcodepre{margin:0em;}
.csharpcode.rem{color:#008000;}
.csharpcode.kwrd{color:#0000ff;}
.csharpcode.str{color:#006080;}
.csharpcode.op{color:#0000c0;}
.csharpcode.preproc{color:#cc6633;}
.csharpcode.asp{background-color:#ffff00;}
.csharpcode.html{color:#800000;}
.csharpcode.attr{color:#ff0000;}
.csharpcode.alt
{
background-color:#f4f4f4;
width:100%;
margin:0em;
}
.csharpcode.lnum{color:#606060;}用.NETReflector载入生成的实体程序集,查看它的资源文件,如上图所示,三个资源文件被嵌入在程序集中。

.csharpcode,.csharpcodepre
{
font-size:small;
color:black;
font-family:consolas,"CourierNew",courier,monospace;
background-color:#ffffff;
/*white-space:pre;*/
}
.csharpcodepre{margin:0em;}
.csharpcode.rem{color:#008000;}
.csharpcode.kwrd{color:#0000ff;}
.csharpcode.str{color:#006080;}
.csharpcode.op{color:#0000c0;}
.csharpcode.preproc{color:#cc6633;}
.csharpcode.asp{background-color:#ffff00;}
.csharpcode.html{color:#800000;}
.csharpcode.attr{color:#ff0000;}
.csharpcode.alt
{
background-color:#f4f4f4;
width:100%;
margin:0em;
}
.csharpcode.lnum{color:#606060;}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: