请高人来帮忙讲讲反射机制和ORM机制~

wiki14 2009-09-05 09:01:31
RT,什么是反射机制和ORM机制?

在项目中应用在什么地方?如何应用?
有什么好处?
请详细讲讲~

如有什么好的简单易懂的资料也可以推荐看看。

小生在此先谢谢大家了!
...全文
940 23 打赏 收藏 转发到动态 举报
写回复
用AI写文章
23 条回复
切换为时间正序
请发表友善的回复…
发表回复
silkstockings 2010-01-20
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 sp1234 的回复:]
反射千万不可滥用,它会让你的程序慢1000倍。但是在必须使用它时,你就要尽可能地发挥其功能。
[/Quote]

我现在有时候直接根据实体类,用反射增加 修改数据库记录,没觉得慢啊!
caotoulei 2009-12-18
  • 打赏
  • 举报
回复
看NHibernate的资历,它就是一种ORM。 你也可以用Linq to SQL自己写mapping file。
xupeihuagudulei 2009-09-05
  • 打赏
  • 举报
回复
周公已经讲的很详细了
NealXX 2009-09-05
  • 打赏
  • 举报
回复
学习了
  • 打赏
  • 举报
回复
同时,IDomain的设计还包括相关的触发器类。

数据库操作被夸张得特别神奇,编写数据库程序对于许多人来说似乎是高级的技术,其实不过也就是IDomain这几个操作而已,对于我(以及我的团队)来说应该说是没有什么技术含量的低级编程技术。
  • 打赏
  • 举报
回复
我对于 ORM 的接口定义是这样的
using System;
using System.Linq;

namespace WuweiCommon
{
public interface IDomain : IDisposable
{
IQueryable<T> Cast<T>() where T : class;
void Insert<T>(T obj) where T : class;
void Update<T>(T obj) where T : class;
void Delete<T>(T obj) where T : class;
void Commit();
}
}


例如写:
            using (var dt = WuweiCommon.Extensions.GetDALInstance ())
{
var tm = dt.Cast<Team>().First(t => t.Name == TeamName);
tm.Name = Team.Name;
dt.Insert(tm);
dt.Commit();
}


当Commit()没有执行(例如抛出异常时),IDisposable.Dispose方法的实现会回滚数据库事务。

而WuweiCommon.Extensions.GetDALInstance方法则是从应用程序的配置文件(app.config或者web.config文件等)来反射获取IDomain的具体实现类型(和对象)。

我实现了超过7、8种IDomain作为产品的基础(临时实现的不算),从面向.net内存集合变量,到4种关系数据库、1种面向对象数据库、xml文件、以及一个大厂家提供的相当变态的远程访问api,都集成在同一个接口之下。
wiki14 2009-09-05
  • 打赏
  • 举报
回复
感谢楼上高人为我解说。
回头好好研究研究,

再看看大家有没有什么好的想法。
  • 打赏
  • 举报
回复
使用反射时,通常仅仅反射一次,然后就将反射出来的各种对象保存(缓存)在static变量中,甚至将反射出来的Method转换为Delegate(因为执行delegate要比执行method.Invoke快很多)。

如果不注意这个,那么反射程序就真的执行很慢了。如果注意了这个,那么尽管反射代码比非反射代码慢1000倍,但是对你的应用程序的运行速度几乎不会产生任何影响,而又具有强大灵活的“看似万能”的功能。
  • 打赏
  • 举报
回复
嗯,那个开源项目是DBLinq,少写了一个字母。
  • 打赏
  • 举报
回复
哇-- 学习学习-
  • 打赏
  • 举报
回复
var u=dbt.GetTable<User>().InsertOnSubmit(u);

应该写为

dbt.GetTable<User>().InsertOnSubmit(u);




我们看到还有很多人(大多数csdn上的人)在使用 “new SqlConnection”、“cmd.Execute.....”之类的代码,一些喜欢抽象、通用化的人使用DBConnection、DBCommand或者是IDbConnection、IDbCommand之类接口。当切换数据库时其实SQL还是要逐一修改、调试。这些人的做法还没有进入Linq操作数据库的门槛,还停留在操作数据库的原始阶段。

网上有个开源项目 DLinq,她可以使用Linq provider处理许多种数据库,所有数据库的Linq接口都是通用的 DbLinq.Data.Linq.DataContext 继承来的,所以所有这些数据库操作方法都有同样的抽象类型,切换不同数据库时你编写的代码几乎从不用改变,因此也就几乎从来不用调试就能保证质量。
  • 打赏
  • 举报
回复
写出增加、删除的demo:
using(var dbt=new DataContext(this.connectionString))
{
var u=new User{LogName="张三",Email="张三@1234.com"};
var u=dbt.GetTable<User>().InsertOnSubmit(u);
dbt.SubmitChanges();
}
using(var dbt=new DataContext(this.connectionString))
{
var table=dbt.GetTable<User>();
var u=table.Where(u=>u.LogName=="1234").First(); //删除1234这个用户
table.DeleteOnSubmit(u);
dbt.SubmitChanges();
}
  • 打赏
  • 举报
回复
反射千万不可滥用,它会让你的程序慢1000倍。但是在必须使用它时,你就要尽可能地发挥其功能。
zhongwei11 2009-09-05
  • 打赏
  • 举报
回复
新手~~进来学习学习~~!!
  • 打赏
  • 举报
回复
给你举个Linq to SQL应用的例子:

假设要查询一个LogName=="1234"的User对象,并且将他的Email修改一下,并保存,就可以写代码:
using(var dbt=new DataContext(this.connectionString))
{
var u=dbt.GetTable<User>().Where(u=>u.LogName=="1234").First();
u.Email="xx@1234.com";
dbt.SubmitChanges();
}


这样,Linq to SQL可以处理任意自定义类型。我只需要手写这个User类型上的Attribute声明:
    [Table]
public class User
{
private static Random Rnd = new Random();

private long _ID = long.MinValue;

[Column(IsPrimaryKey=true)]
public long ID
{
get
{
if (_ID == long.MinValue)
_ID = (long)Rnd.Next() + DateTime.Now.Ticks;
return _ID;
}
set { _ID = value; }
}

private string _LogName;

[Column(DbType="nvarchar(40) NOT NULL")]
public string LogName
{
get { return _LogName; }
set { _LogName = value; }
}

[Column(DbType = "varbinary(32) NULL")]
private byte[] PasswordMD5 { set; get; }

private string _EMail;

[Column(DbType = "nvarchar(100) NOT NULL")]
public string EMail
{
get { return _EMail; }
set { _EMail = value; }
}

[Column(DbType = "bit NOT NULL")]
public bool DenyLogin { get; set; }


尽管大多数Linq to SQL的网上教程都教你在vs环境帮助下自动产生 .dbml 文件并自动产生相应的从 DataContext继承的数据源对象的方法,其实根本不需要,像这样仅仅在自定义的实体对象上定义相应的Attribute就可以使用Linq to SQL直接访问数据库了。

Linq to SQL框架设计开发在先,然后你才使用它来编写你的数据库应用程序。这就是最关键的需求——对象的类型、属性等等都是在开发框架时预先不知道、无法想当然地用接口或者抽象class来假设的,但是你只要通知Linq to SQL,它就能解析并执行相应的功能。
周公 2009-09-05
  • 打赏
  • 举报
回复
程序集包含模块,而模块包含类型,类型又包含成员。反射则提供了封装程序集、模块和类型的对象。您可以使用反射动态地创建类型的实例,将类型绑定到现有对象,或从现有对象中获取类型。然后,可以调用类型的方法或访问其字段和属性。反射通常具有以下用途:
  1.使用 Assembly 定义和加载程序集,加载在程序集清单中列出的模块,以及从此程序集中查找类型并创建该类型的实例。
  2.使用 Module 了解如下的类似信息:包含模块的程序集以及模块中的类等。您还可以获取在模块上定义的所有全局方法或其他特定的非全局方法。
  3.使用 ConstructorInfo 了解如下的类似信息:构造函数的名称、参数、访问修饰符(如 public 或 private)和实现详细信息(如 abstract 或 virtual)等。
  4.使用 Type 的 GetConstructors 或 GetConstructor 方法来调用特定的构造函数。
  5.使用 MethodInfo 来了解如下的类似信息:方法的名称、返回类型、参数、访问修饰符(如 public 或 private)和实现详细信息(如 abstract 或 virtual)等。使用 Type 的 GetMethods 或 GetMethod 方法来调用特定的方法。
  6.使用 FieldInfo 来了解如下的类似信息:字段的名称、访问修饰符(如 public 或 private)和实现详细信息(如 static)等;并获取或设置字段值。
  7.使用 EventInfo 来了解如下的类似信息:事件的名称、事件处理程序数据类型、自定义属性、声明类型和反射类型等;并添加或移除事件处理程序。
  8.使用 PropertyInfo 来了解如下的类似信息:属性的名称、数据类型、声明类型、反射类型和只读或可写状态等;并获取或设置属性值。
  9.使用 ParameterInfo 来了解如下的类似信息:参数的名称、数据类型、参数是输入参数还是输出参数,以及参数在方法签名中的位置等。
周公 2009-09-05
  • 打赏
  • 举报
回复
对象-关系数据库映射
  什么是ORM?
  对象关系映射(ORM)提供了概念性的、易于理解的模型化数据的方法。ORM方法论基于三个核心原则:
  简单:以最基本的形式建模数据。
  传达性:数据库结构被任何人都能理解的语言文档化。
  精确性:基于数据模型创建正确标准化了的结构。
  典型地,建模者通过收集来自那些熟悉应用程序但不熟练的数据建模者的人的信息开发信息模型。建模者必须能够用非技术企业专家可以理解的术语在概念层次上与数据结构进行通讯。建模者也必须能以简单的单元分析信息,对样本数据进行处理。ORM专门被设计为改进这种联系。
  规则表达式
  ORM把应用程序世界表示为具有角色(关系中的部分)的一组对象(实体或值)。ORM有时也称为基于事实的建模,因为它把相关数据描述为基本事实。这些事实如果分割为再小的事实就会丢失信息。
  简单事实的一些例子包括:
  人有电话
  人住在某个地方
  人生于某个日期
  人在某个日期被雇佣
  ORM提供的不只是描述不同对象间关系的一个简单而直接的方式。ORM还提供了灵活性。使用ORM创建的模型比使用其它方法创建的模型更有能力适应系统的变化。另外,ORM允许非技术企业专家按样本数据谈论模型,因此他们可以使用真实世界的数据验证模型。因为ORM允许重用对象,数据模型能自动映射到正确标准化的数据库结构。
  ORM模型的简单性简化了数据库查询过程。使用ORM查询工具,用户可以访问期望数据,而不必理解数据库的底层结构。
  =================================================================================================
  对象关系映射(Object Relational Mapping,简称ORM)是一种为了解决面向对象与关系数据库存在的互不匹配的现象的技术。 简单的说,ORM是通过使用描述对象和数据库之间映射的元数据,将java程序中的对象自动持久化到关系数据库中。本质上就是将数据从一种形式转换到另外一种形式。 这也同时暗示者额外的执行开销;然而,如果ORM作为一种中间件实现,则会有很多机会做优化,而这些在手写的持久层并不存在。 更重要的是用于控制转换的元数据需要提供和管理;但是同样,这些花费要比维护手写的方案要少;而且就算是遵守ODMG规范的对象数据库依然需要类级别的元数据。
  对象-关系映射(Object/Relation Mapping,简称ORM),是随着面向对象的软件开发方法发展而产生的。面向对象的开发方法是当今企业级应用开发环境中的主流开发方法,关系数据库是企业级应用环境中永久存放数据的主流数据存储系统。对象和关系数据是业务实体的两种表现形式,业务实体在内存中表现为对象,在数据库中表现为关系数据。内存中的对象之间存在关联和继承关系,而在数据库中,关系数据无法直接表达多对多关联和继承关系。因此,对象-关系映射(ORM)系统一般以中间件的形式存在,主要实现程序对象到关系数据库数据的映射。
  面向对象是从软件工程基本原则(如耦合、聚合、封装)的基础上发展起来的,而关系数据库则是从数学理论发展而来的,两套理论存在显著的区别。为了解决这个不匹配的现象,对象关系映射技术应运而生。
  让我们从O/R开始。字母O起源于"对象"(Object),而R则来自于"关系"(Relational)。几乎所有的程序里面,都存在对象和关系数据库。在业务逻辑层和用户界面层中,我们是面向对象的。当对象信息发生变化的时候,我们需要把对象的信息保存在关系数据库中。
  当你开发一个应用程序的时候(不使用O/R Mapping),你可能会写不少数据访问层的代码,用来从数据库保存,删除,读取对象信息,等等。你在DAL中写了很多的方法来读取对象数据,改变状态对象等等任务。而这些代码写起来总是重复的。
  如果打开你最近的程序,看看DAL代码,你肯定会看到很多近似的通用的模式。我们以保存对象的方法为例,你传入一个对象,为SqlCommand对象添加SqlParameter,把所有属性和对象对应,设置SqlCommand的CommandText属性为存储过程,然后运行SqlCommand。对于每个对象都要重复的写这些代码。
  除此之外,还有更好的办法吗?有,引入一个O/R Mapping。实质上,一个O/R Mapping会为你生成DAL。与其自己写DAL代码,不如用O/R Mapping。你用O/R Mapping保存,删除,读取对象,O/R Mapping负责生成SQL,你只需要关心对象就好。
  对象关系映射成功运用在不同的面向对象持久层产品中,如:Torque,OJB,Hibernate,TopLink,Castor JDO, TJDO 等。
  一般的ORM包括以下四部分:
  一个对持久类对象进行CRUD操作的API;
  一个语言或API用来规定与类和类属性相关的查询;
  一个规定mapping metadata的工具;
  一种技术可以让ORM的实现同事务对象一起进行dirty checking, lazy association fetching以及其他的优化操作。
  一、目前流行的 ORM 产品
  目前众多厂商和开源社区都提供了持久层框架的实现,常见的有:
  Apache OJB (http://db.apache.org/ojb/)
  Cayenne (http://objectstyle.org/cayenne/)
  Jaxor (http://jaxor.sourceforge.net)
  Hibernate (http://www.hibernate.org)
  iBatis (http://www.ibatis.com)
  jRelationalFramework (http://ijf.sourceforge.net)
  mirage (http://itor.cq2.org/en/oss/mirage/toon)
  SMYLE (http://www.drjava.de/smyle)
  TopLink (http://otn.oracle.com/products/ias/toplink/index.html)
  其中 TopLink 是 Oracle 的商业产品,其他均为开源项目。
  其中 Hibernate 的轻量级 ORM 模型逐步确立了在 Java ORM 架构中领导地位,甚至取代复杂而又繁琐的 EJB 模型而成为事实上的 Java ORM 工业标准。而且其中的许多设计均被 J2EE 标准组织吸纳而成为最新 EJB 3.0 规范的标准,这也是开源项目影响工业领域标准的有力见证。
  二、对象-关系映射模式
  从《公共仓库元模型:开发指南》一书第8章CWM元仓库中摘录出来的内容,实现了公共仓库元模型(CWM)的UML图到Microsoft SQL Server数据库的映射,是一种将对象层次结构映射成关系型结构的方法。个人认为可以作为将本体(Ontology)文件存储到关系型数据库中的一种可借鉴方法。
  基本情况:公共仓库元模型(CWM)是对象管理组织(OMG)的一种和数据仓库相关的元模型标准,采用UML表示的对象层次结构,在保存到数据库中时由于面向对象的数据库技术的不完善(理论研究和商业应用都不是主流),所以该书的作者倾向于使用成熟的关系型数据库来保存-这也是存储本体时所遇到的问题。
  采用方法:将UML模型中的各种元素通过转换,保存为数据库模式。由于CWM是一种元模型,因此模型的实例也是一种模型,将这种实例以数据库数据的形式保存。使用数据库中比较成熟的存储过程技术提高开发和执行效率。
  1、数据类型映射模式
  1.1简单数据类型模式:建立UML和关系型数据库中简单数据类型的映射表以指导映射。
  1.2枚举数据类型模式:每种枚举类型对应一个表,只有一个列(_EnumLiteral)表示枚举值。
  1.3基于类的数据类型模式:使用外键约束,将基础列与基于类的类型实例相关联。
  2、类映射模型
  每个类对应一个表。单值属性、多值属性、继承关系可以用下述方法映射,而引用属性将在关联映射模式中提到。
  2.1单值属性模式:是cardinality的上界为1的属性,映射到类所对应的表的列上。若其下界也为1(必须有的属性),列属性为NOT NULL。
  2.2多值属性模式:每个多值属性映射成一个独立的表,使用外键连接到类所对应的表上。
  2.3继承模式:每加入一个类的实例时,根据其继承关系自顶向下生成每个类的对象,这些对象具有相同的ID(根对象对应记录的主键)。删除对象实例时,自底向上删除数据。遇到从中间删的情况怎么办?多重继承怎么处理?(金龙飞)
  3、关联映射模式
  3.1一对一关联模式:在关联两端各加一列。
  3.2一对多关联模式:和3.1一样。如果多这端是有序的,还需加入一列表示序号。
  3.3多对多关联模式:将关联单独作一个表。
  3.4组合关联模式:注意级联式删除。
  3.5反演关联模式:关联两端指向相关的类型,和普通关联一样。
  3.6成对关联模式:关联记录两个类间的关系,用交集类表示关联,表示成一个单独的表,每个关联对应一个表,用外键表示它们间的关系。
  3.7关联上的OCL需要分析成对应的存储过程代码。
  3.8保证关联的cardinality也需要分析成对应的存储过程代码。
  4、引用映射模式
  在UML中不存在的MOF特征,指属性是声明为引用类型的实例。用存储过程实现。
wiki14 2009-09-05
  • 打赏
  • 举报
回复
..........来个人吧.
..........自己顶一下.
微创社(MCC) 2009-09-05
  • 打赏
  • 举报
回复
LINQ 2 XXX
ld1201 2009-09-05
  • 打赏
  • 举报
回复
先学c#语法。在学petshop
然后学orm框架
加载更多回复(2)

110,502

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧