前一篇文章介绍了应用LLBL Gen生成Entity Framework所需要的类型定义,用一行代码完成数据资料的读取,
《LLBL Gen + Entity Framework 程序设计入门》。如果已经对Entity Framework产生兴趣,则可以借助于这一篇,来学习Entity Framework如何对资料库进行操作。
连接字符串的写法 Database Connection String
string con ="name = ConnectionString.SQL Server (SqlClient)" ;
其中的”ConnectionString.SQL Server (SqlClient)”是配置文件中的连接字符串名称,App.config的文件内容如下
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<connectionStrings>
<!-- please adjust the connection string embedded in the element below to target the proper catalog / server using the proper user / password combination -->
<add name="ConnectionString.SQL Server (SqlClient)" connectionString="metadata=res://*/Entity35.csdl|res://*/Entity35.ssdl|res://*/Entity35.msl;provider=System.Data.SqlClient;provider connection string="data source=.\sqlexpress;initial catalog=Framework;integrated security=SSPI;persist security info=False;packet size=4096"" providerName="System.Data.EntityClient" />
</connectionStrings>
</configuration>
.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { 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; }
或者直接在代码中嵌入上面的连接字符串的值
string conn="ConnectionString.SQL Server (SqlClient)" connectionString="metadata=res://*/Entity35.csdl|res://*/Entity35.ssdl|res://*/Entity35.msl;provider=System.Data.SqlClient;provider connection string="data source=.\sqlexpress;initial catalog=Framework;integrated security=SSPI;persist security info=False;packet size=4096"" providerName="System.Data.EntityClient";
如果担心字符串的方法会报错或是需要动态建立连接字符串,可以构造EntityConnectionStringBuilder类型来生成连接字符串。
// Specify the provider name, server and database.
string providerName = "System.Data.SqlClient";
string serverName = ".";
string databaseName = "AdventureWorks"; // Initialize the connection string builder for the underlying provider.
SqlConnectionStringBuilder sqlBuilder =new SqlConnectionStringBuilder(); // Set the properties for the data source.
sqlBuilder.DataSource = serverName;
sqlBuilder.InitialCatalog = databaseName;
sqlBuilder.IntegratedSecurity = true; // Build the SqlConnection connection string.
string providerString = sqlBuilder.ToString(); // Initialize the EntityConnectionStringBuilder.
EntityConnectionStringBuilder entityBuilder =new EntityConnectionStringBuilder();
//Set the provider name.
entityBuilder.Provider = providerName;
// Set the provider-specific connection string.
entityBuilder.ProviderConnectionString = providerString;
// Set the Metadata location.
entityBuilder.Metadata = @"res://*/AdventureWorksModel.csdl|
res://*/AdventureWorksModel.ssdl|
res://*/AdventureWorksModel.msl";
Console.WriteLine(entityBuilder.ToString());
创建新数据 Create Record
创建一笔新的配置项数据,把它保存到数据库中,有二种方法:AddToX或是AddObject,然后调用SaveChanges
Entity35DataContext dataContext = new Entity35DataContext(); Configuration configuration = new Configuration();
configuration.MasterKey = "James";
configuration.Description = "My Profile";
// save configuration
dataContext.AddToConfigurations(configuration);.
dataContext.SaveChanges();
//save configruation
dataContext.AddObject("Configuration",configuration);
dataContext.SaveChanges();
注意必须输入的数据库字段(NOT NULL)必须要有值,否则会抛出数据库异常。
更新数据 Update Record
Configuration configuration.....
configuration.Description="New Profile";
dataContext.SaveChanges();
在更改实体的映射属性之后,调用SaveChanges即可将修改后的属性值保存到数据库中。
如果要更新的属性所映射的是数据表的主键,不应该直接更新主键,这样会报错,而应该先删除,再创建一笔新的记录。
.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { 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; }
删除数据 Delete Record
Configuration configuraion.....
dataContext.DeleteObject(configuration);
.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { 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; }
被删除的对象configuration,可以是已经读取了映射的表的实体,也可以没有映射过值的对象,构造一个新的内存对象,再把它传给DeleteObject方法。我认为这个方法的内部实现应该只需要去查找这个实体的主键,生成相应的SQL语句即可。
事务 Transaction
如果需要对多个对象进行操作,事务支持可以用dataContext的Connection对象,代码例子如下
Entity35DataContext dataContext = null;
System.Data.Common.DbTransaction tran = null;
try
{
dataContext = new Entity35DataContext();
dataContext.Connection.Open();
tran = dataContext.Connection.BeginTransaction();
Configuration cst = dataContext.Configurations.FirstOrDefault(cc => cc.MasterKey == "James");
cst.Description = "China ";
dataContext.SaveChanges();
tran.Commit();
}
catch (Exception ex)
{
if (tran != null) tran.Rollback();
throw ex;
}
finally
{
if (dataContext != null && dataContext.Connection.State != ConnectionState.Closed)
dataContext.Connection.Close();
}
应用Repository 模式 Apply Repository Pattern
将上面的CRUD操作应用Repository模式封装,以隔离变化。
public interface IConfigurationRepository
{
// Query Methods
IQueryable<Configuration> FindAllConfiguration();
Configuration GetConfiguration(string key); // Insert/Delete
void Add(Configuration configuration);
void Delete(Configuration configuration); // Persistence
void Save();
}
可以考虑借助于Code Smith代码生成工具,直接生成这个接口模板,它的实现代码也非常容易。
查询 Entity Query
Entity Framework有二种方法写数据查询,一种是上面展示的Linq to Entity,它是延迟执行的。另一种是Entity SQL。这种写法维护起来相对复杂一些,不过性能会好一些。比如一个表有100个字段,Linq to Entity会将这100个字段的值会部读出来,映射到内存对象中,当数据量很大的时候,这种写法会产生性能瓶颈。有时候,我们也只需要读取表的若干个字段,而不是全部,所以有必要研究一下Entity SQL的写法。
对象查询 VALUES
SELECT VALUE it FROM FrameworkEntities.Configuration as it
.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { 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; }这种写示会读取数据表的所有字段,然后构造成Configuration对象,it是查询对象的别名。
带参数查询
SELECT VALUE it FROM FrameworkEntities.Configuration as it
where it.MasterKey=@MasterKey
.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { 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; }聚合函数
SELECT count(1) FROM FrameworkEntities.Configuration
.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { 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; }Top查询
SELECT top(10) it.MasterKey FROM FrameworkEntities.Configuration as it
.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { 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; }Row
SELECT VALUES row(it.MasterKey,it.Description) FROM FrameworkEntities.Configuration as it
这种写法会构造一个匿名类型,只读取指定的字段值,返回匿名对象。
Key 主键
SELECT VALUE key(it) FROM FrameworkEntities.Configuration as it
.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { 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; }返回Configuration表的主键
.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { 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, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { 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; }