DataContext的讨论(1):
谢谢访问我的blogs!
本来计划DataContext是一篇写完的,但太长拉,不是很好.所以就分成两部分,第二部分会有disconnect work,写LINQ to SQL与传统的ORM不同和更多吧.
一.是使用ObjectDumper
ObjectDumper: A utility for writing the output from a LINQ query to the screen in text mode.
这个对象就是通过反射你传入的对象的元素和域,再将他们反射出来的值输出到Console Windons,
ObjectDumper.Write(custs);
二:对LINQ 使用collections的总结
List<T>
System.Collections.Generic.List<T>
■ System.Collections.Generic.LinkedList<T>
■ System.Collections.Generic.Queue<T>
■ System.Collections.Generic.Stack<T>
■ System.Collections.Generic.HashSet<T>
■ System.Collections.ObjectModel.Collection<T>
■ System.ComponentModel.BindingList<T>
Generic dictionaries
System.Collections.Generic.Dictionary<TKey,TValue>
■ System.Collections.Generic.SortedDictionary<TKey, TValue>
■ System.Collections.Generic.SortedList<TKey, TValue>
主要也就是上面这两个.一般LINQ 查询的数据其实就是查询list.
三:相比一下LINQ,Query,LINQ to SQL有什么不同
Query | LINQ | LINQ to SQL |
Item | Query variable | return type |
Data source | IEnumerable IQueryable | specification From/from |
equivalent | Filtering | Where/where |
equivalent | Grouping | Groupby |
equivalent | Selecting | Select/select |
equivalent | Joins join | Association attribute |
他们使用的组件不同: | ||
ADO Provider | LINQ to SQL API | LINQ to SQL Provider |
四:DataContext
DataContext的目的是转换你的请求的对象为SQL查询影响数据库,并且,这里DataContext受权LINQ实现Standard Query Operators,LINQ to SQL是翻译查询为SQL语句返回服务端.
在上一篇中我们谈过LINQ to SQL的对象模型,里面知道DataContext对应的就是数据库,主要原因就是DataContext同过设置连接字符串参数后就能连接到数据库.而我们又将数据库中的表和关系通过ORM生成对象放在内存(标识放在内存)中.
其中使用DataContext最基本的方式是:
DataContext db
=
new
DataContext(
" Initial Catalog=AdventureWorks;Integrated i
Security = sspi " );
" Initial Catalog=AdventureWorks;Integrated i
Security = sspi " );
如果你要先了解DataContext你可以先使用LINQ to SQL provieder生成.dbml文件,查看里面.cs文件.你就能看见DataContext的一些使用.
[System.Data.Linq.Mapping.DatabaseAttribute(Name
=
"
Northwind
"
)]
public partial class VLinqDataClassesDataContext : System.Data.Linq.DataContext
{
private static System.Data.Linq.Mapping.MappingSource mappingSource = new AttributeMappingSource();
public VLinqDataClassesDataContext() :
base(global::CSharpLanguage_C_app.Properties.Settings.Default.NorthwindConnectionString, mappingSource)
{
OnCreated();
}
public VLinqDataClassesDataContext(string connection) :
base(connection, mappingSource)
{
OnCreated();
}
public VLinqDataClassesDataContext(System.Data.IDbConnection connection) :
base(connection, mappingSource)
{
OnCreated();
}
public VLinqDataClassesDataContext(string connection, System.Data.Linq.Mapping.MappingSource mappingSource) :
base(connection, mappingSource)
{
OnCreated();
}
public VLinqDataClassesDataContext(System.Data.IDbConnection connection, System.Data.Linq.Mapping.MappingSource mappingSource) :
base(connection, mappingSource)
{
OnCreated();
}
}
public partial class VLinqDataClassesDataContext : System.Data.Linq.DataContext
{
private static System.Data.Linq.Mapping.MappingSource mappingSource = new AttributeMappingSource();
public VLinqDataClassesDataContext() :
base(global::CSharpLanguage_C_app.Properties.Settings.Default.NorthwindConnectionString, mappingSource)
{
OnCreated();
}
public VLinqDataClassesDataContext(string connection) :
base(connection, mappingSource)
{
OnCreated();
}
public VLinqDataClassesDataContext(System.Data.IDbConnection connection) :
base(connection, mappingSource)
{
OnCreated();
}
public VLinqDataClassesDataContext(string connection, System.Data.Linq.Mapping.MappingSource mappingSource) :
base(connection, mappingSource)
{
OnCreated();
}
public VLinqDataClassesDataContext(System.Data.IDbConnection connection, System.Data.Linq.Mapping.MappingSource mappingSource) :
base(connection, mappingSource)
{
OnCreated();
}
}
可以看出DataContext有多个重载,我们可以很清楚的看见它的几个被重载的函数;
你能通过一个IDbConnection(表示打开连接数据源).IDbConncetion是一个定义在System.Data.命名空间的接口,允许继承这个接口实现一个Conncetion类,包括一个唯一的访问数据源的Session.这样做的好处就是应用程序不要立刻创建一个IDbConncetion的实例.而是创建的是一个继承它的类的实例.(现在已经解释两个拉!).
这一个:
mappingSource是表示一个mapping信息,是绘制CLR对象到entities.它有两个方法CreateModel方法和GetModel方法,GreateModel方法是用来,返回一个匹配当恰mapping schema所创建的meta-model.GetModel方法就是返回一个meta-model.meta-model是表示数据库和domain object(域对象)之间的映射的一个抽象(就是他们之间的描述资源).就是有CLR type system 和 SQL database之间的信息.你可以从这个类中得到用户在数据库中自定义的函数,得到从数据库表中得到的columns映射到domain object的类型,还有数据库中的表名等相关信息.还有AttributeMappingSource是继承MappingSource类,它是在context中的attributes去创建一个mapping model.
来看都使用怎样得到的
//强类型的dataContext就自己写拉!
Northwnd nw
=
new
Northwnd();
var model = new AttributeMappingSource().GetModel( typeof (Northwind));
foreach (var mt in model.GetTables())
Console.WriteLine(mt.TableName);
var model2 = nw.Mapping;
foreach (var mt2 in model2.GetTables())
{
Console.WriteLine(mt2.TableName);
}
Console.ReadLine();
var model = new AttributeMappingSource().GetModel( typeof (Northwind));
foreach (var mt in model.GetTables())
Console.WriteLine(mt.TableName);
var model2 = nw.Mapping;
foreach (var mt2 in model2.GetTables())
{
Console.WriteLine(mt2.TableName);
}
Console.ReadLine();
到现在都没有使用DataContext,但我们却能找到DataContext中Mapping数据库后进入.NET 系统的相关信息
var model3
=
new
AttributeMappingSource().GetModel(
typeof
(Northwnd));
foreach (var mt3 in model3.GetTables())
{
Console.WriteLine(mt3.TableName);
foreach (var dm in mt3.RowType.DataMembers)
{
Console.WriteLine("Column{0}",dm.MappedName);
Console.WriteLine(dm.AutoSync);
Console.WriteLine(dm.CanBeNull);
//Console.WriteLine(dm.DeferredValueAccessor.Type);
//Console.WriteLine(dm.DeferredSourceAccessor.Type);
Console.WriteLine(dm.UpdateCheck);
Console.WriteLine(dm.Member.MemberType);
Console.WriteLine(dm.IsPrimaryKey);
Console.WriteLine(dm.IsDiscriminator);
Console.WriteLine(dm.IsDeferred);
//Console.WriteLine(dm.Association.IsMany);
//Console.WriteLine(dm.Association.OtherKey);
//Console.WriteLine(dm.Association.ThisKeyIsPrimaryKey);
//Console.WriteLine(dm.Association.ThisKey);
//Console.WriteLine(dm.Association.IsForeignKey);
//Console.WriteLine(dm.Association.DeleteRule);
}
}
Console.ReadLine();
foreach (var mt3 in model3.GetTables())
{
Console.WriteLine(mt3.TableName);
foreach (var dm in mt3.RowType.DataMembers)
{
Console.WriteLine("Column{0}",dm.MappedName);
Console.WriteLine(dm.AutoSync);
Console.WriteLine(dm.CanBeNull);
//Console.WriteLine(dm.DeferredValueAccessor.Type);
//Console.WriteLine(dm.DeferredSourceAccessor.Type);
Console.WriteLine(dm.UpdateCheck);
Console.WriteLine(dm.Member.MemberType);
Console.WriteLine(dm.IsPrimaryKey);
Console.WriteLine(dm.IsDiscriminator);
Console.WriteLine(dm.IsDeferred);
//Console.WriteLine(dm.Association.IsMany);
//Console.WriteLine(dm.Association.OtherKey);
//Console.WriteLine(dm.Association.ThisKeyIsPrimaryKey);
//Console.WriteLine(dm.Association.ThisKey);
//Console.WriteLine(dm.Association.IsForeignKey);
//Console.WriteLine(dm.Association.DeleteRule);
}
}
Console.ReadLine();
所以可以看出在第三种重载中参数就是一个连接字符串和一个Mapping资源描述,就能找回数据.其他两种就是他们的结合.
五:DataContext的成员
在本篇中对DataContext的成员的介绍如果和删除,修改就放在以后的文章中谈,还有和性能有关的我们放在性能的文章中来谈,所以就只有下面几个方法和属性拉.如果你还要对DataContext深入的研究,你可以到这一篇文章中,这里谈的是 domain model(帅哥"martin Fowler")的应用.
(1)GetTable(TEntity)泛型方法
public Table<TEntity> GetTable<TEntity>() where TEntity : class
返回通过TEntity指定类型的有详细类型的对象集合.这里分直接实例DataContext是:
DataContext dbContext = new DataContext( " Data Source=localhost;Initial Catalog=Northwind;Integrated Security=true; " );
Table < customer > customerTable = dbContext.GetTable < customer > ();
而强类型的DataContext这个方法就被封装
public
partial
class
Northwnd : DataContext
{
private static MappingSource mappingSource = new AttributeMappingSource();
public Northwnd() : base(global::CSharpLanguage_C_app.Properties.Settings.Default.NorthwindConnectionString, mappingSource) { }
public Table<customer> Customers
{
get
{
return this.GetTable<customer>();
}
}
}
{
private static MappingSource mappingSource = new AttributeMappingSource();
public Northwnd() : base(global::CSharpLanguage_C_app.Properties.Settings.Default.NorthwindConnectionString, mappingSource) { }
public Table<customer> Customers
{
get
{
return this.GetTable<customer>();
}
}
}
它还有一个弱类型的GetTable(Type)方法;是一个相关动态查询.反射一个泛型方法做为参数.
public
ITable GetTable(
Type type
)
Type type
)
这个以后到LINQ Dynamic部分我再关注.(可以看我翻译的 这篇和这 里)
(2)DataContext.CreateDatabase方法:
能在服务端创建一个数据库.
在几种情况下你会使用上它:
- 你需要构建一个应用程序动态安装在客户系统中.
- 你构建一个客户端应用程序需要保存数据在本数据库中保持离线状态.
在使用前你需要使用attributes对你的实体做出描述,后再使用.
(3)DatabaseExists方法
确定相应的数据库是否被打开.是通过使用Connection 属性去打开相应的数据库.
(3)deleteDatabase
删除相应的数据库
string
userTempFolder
=
Environment.GetEnvironmentVariable(
"
Temp
"
);
string userMDF = System.IO.Path.Combine(userTempFolder, @" Northwind " );
Northwnd newBb = new Northwnd(userMDF);
if (newBb.DatabaseExists())
{
Console.WriteLine("CreateDB DB exists");
newBb.DeleteDatabase();
}
else
{
Console.WriteLine("Delete DB does not exist");
newBb.CreateDatabase();
}
string userMDF = System.IO.Path.Combine(userTempFolder, @" Northwind " );
Northwnd newBb = new Northwnd(userMDF);
if (newBb.DatabaseExists())
{
Console.WriteLine("CreateDB DB exists");
newBb.DeleteDatabase();
}
else
{
Console.WriteLine("Delete DB does not exist");
newBb.CreateDatabase();
}
(4)Log Property
可以将SQL命令的输出写到到指定文件中,主要我们是通过重写输出对象来做到的.(这里很灵活)
1:输出到
Debugger window: context.Log
=
new
DebuggerWriter();
2:在页面上输出SQL语句可以在这里 下载:
3:将LOG里面输出的内容写到一个文本里面:
StreamWriter writer
=
new
StreamWriter(HttpContext.Current.Request.PhysicalApplicationPath
+
"
DataContextLog.txt
"
,
true
);
DataContext.Log = writer;
DataContext.Log = writer;
有很多方式.
(5)Connection属性
返回一个Connection.
还有更高级的部分在 DataContext的讨论(1)会谈到。
worksguo
www.cnblogs.com