相关软件的CDKEY整理

一、[CD-KEY]Microsoft Office SharePoint Server 2007 简体中文版
Tkjcb-3wkhk-2ty2t-qymk2-9xm2y


二、[CD-KEY]Microsoft Office Project Server 2007简体中文版
CD-KEY: JBRXG-J92WH-8C3K8-B3TW3-99TKG


三、Office 2007企业版/专业版通用序列号:DBXYD-TF477-46YM4-W74MH-6YDQ8


四、[CD-KEY]Project Portfolio Server 2007 英文版本
QRPKT-683CC-MJ9VJ-FHBCC-HYKGD


五、VS2008正式版序列号CDKEY:PYHYP-WXB3B-B2CCM-V9DX9-VDY8T


六、Visual Studio 2008 Team Foundation Server: WPDW8-M962C-VJX9M-HQB4Q-JVTDM


七、VS2008简体中文正式版序列号

1.Visual Studio 2008 Professional Edition:
XMQ2Y-4T3V6-XJ48Y-D3K2V-6C4WT

2.Visual Studio 2008 Team Test Load Agent:
WPX3J-BXC3W-BPYWP-PJ8CM-F7M8T

3.Visual Studio 2008 Team System:
PYHYP-WXB3B-B2CCM-V9DX9-VDY8T

4.Visual Studio 2008 Team Foundation Server:
WPDW8-M962C-VJX9M-HQB4Q-JVTDM

-----------------------------------------------------------------
把90天试用版改为正式版,二种方法:

1. 把Setup\setup.sdb文件中的
[Product Key]
T2CRQGDKBVW7KJR8C6CKXMW3D
改成
[Product Key]
PYHYPWXB3BB2CCMV9DX9VDY8T

2.安装完成后,在“控制面板”中启动“添加删除程序”,选中Vs2008,点击“更改、删除”,
输入序列号:PYHYP-WXB3B-B2CCM-V9DX9-VDY8T

---------------------------------
Visual Studio Team System 2008 Team Suite(90 天试用版)
http://www.microsoft.com/downloads/details.aspx?FamilyId=D95598D7-AA6E-4F24-82E3-81570C5384CB&displaylang=zh-cn#Requirements

posted @ 2008-07-31 12:27 懒惰的车轮 阅读(109) | 评论 (1)编辑

 

把sql server 2005的数据库向sql server 2000数据库进行---附加数据库 错误602
错误描述:
未能在 sysindexes 中找到数据库 ID 13 中对象 ID 1 的索引 ID 1 对应的行。请对 sysindexes 运行 DBCC CHECKTABLE。
Could not find row in sysindexes for database ID 13, object ID 1, index ID 1. Run DBCC CHECKTABLE on sysindexes.
未能打开新数据库 'XXXX'。CREATE DATABASE 将终止。 (Microsoft SQL Server,错误: 602)
解决办法:
因为数据库附加到2005的时候, 数据库文件已经自动升级到2005, 所以在2000下是无法再附加的(没有向上兼容的)直接restore或附加是不行的, 用脚本+导数据肯定没有问题。
2005转到2000的步骤步骤
1. 生成for 2000版本的数据库脚本
2005 的manger studio
-- 打开"对象资源管理器"(没有的话按F8), 连接到你的实例
-- 右键要转到2000的库
-- 任务
-- 生成脚本
-- 在"脚本向导"的"选择数据库"中, 确定选择的是要转到2000的库
-- 勾选"为所选数据库中的所有对象编写脚本"
-- 在接下来的"选择脚本选项"中, 找到"为服务器版本编写脚本"项, 选择"SQL Server 2000"
-- 其他选项根据需要设置
-- 最后把脚本保存到一个 .sql 脚本文件

2. 在2000中创建目标数据库
在查询分析器(或2005的manger studio在打开脚本文件), 连接到SQL Server 2000,执行上面生成的脚本.以创建一个新的数据库

3. 将数据从2005导到2000
2005 的manger studio
-- 打开"对象资源管理器"(没有的话按F8), 连接到你的实例
-- 右键要转到2000的库
-- 任务
-- 导出数据
-- 在"SQL Server 导入和导出向导"的"选择数据源"步骤中, 确定选择的是要导出的数 据库
-- 在"选择目标"步骤中, 连接到 2000, 并选择步骤2新建的库
-- 在"选择源表和源视图"中, 选择所有的表
-- 最后完成
posted @ 2008-07-22 15:24 懒惰的车轮 阅读(255) | 评论 (0)编辑
成批更改sql server数据库所有者的对象

因为一些网站是使用虚拟主机.用sql-server导数据上去的话.
数据库的用户默认是你登录的用户,不是dbo,有时就和本地产生不一致.

--功能说明:成批更改数据库所有者的对象
--作者:不详
--用法:exec ChangeObjectOwner 'nmkspro','dbo'
--即可将所有nmkspro所有者的对象改为dbo所有
--运行成功后将提示:"注意: 更改对象名的任一部分都可能破坏脚本和存储过程。"
CREATE PROCEDURE dbo.ChangeObjectOwner
@OldOwner as NVARCHAR(128),--参数原所有者
@NewOwner as NVARCHAR(128)--参数新所有者
AS

DECLARE @Name   as NVARCHAR(128)
DECLARE @Owner as NVARCHAR(128)
DECLARE @OwnerName as NVARCHAR(128)

DECLARE curObject CURSOR FOR
select 'Name'   = name,
'Owner'   = user_name(uid)
from sysobjects
where user_name(uid)=@OldOwner
order by name

OPEN curObject
FETCH NEXT FROM curObject INTO @Name, @Owner
WHILE(@@FETCH_STATUS=0)
BEGIN  
if @Owner=@OldOwner
begin
set @OwnerName = @OldOwner + '.' + rtrim(@Name)
exec sp_changeobjectowner @OwnerName, @NewOwner
end

FETCH NEXT FROM curObject INTO @Name, @Owner
END

close curObject
deallocate curObject
GO


批量修改:
EXEC sp_MSforeachtable 'exec sp_changeobjectowner ''?'',''dbo'' '
单个修改:
exec sp_changeobjectowner '要改的表名','dbo'


方法一:直接点击该表-》设计-》属性-》更改上面的所有者。该方法针对于表少的情况下。
方法二:利用脚本直接执行,用系统帐号或者超户登陆到该数据库,然后执行下面语句:
sp_configure 'allow updates','1'
go
reconfigure with override
go
update sysobjects set uid=1 where uid<>1 --根据条件可以任意修改,在多用户之间切换。
go
sp_configure 'allow updates','0'
go
reconfigure with override

posted @ 2007-04-12 11:21 懒惰的车轮 阅读(407) | 评论 (0)编辑
 您想连接到Windows Server 2003的“远程桌面”维护服务器,但是客户机却没有终端访问工具。这时您是不是很着急呢?如果您遇到过这种情况,那么下文介绍的内容也许会对您有所帮助。

与Windows 2000相比,Widows Server 2003在远程维护服务器方面一个最明显的改进就是提供了“远程桌面”功能,该功能可以帮助网络管理员十分方便地远程维护服务器。不过要想使用该功能,除了必须在服务端允许远程连接到服务器外,客户机还要有连接“远程桌面”的终端访问工具。这对于系统平台是Windows XP的客户机而言并不是难事(因为其自身已经集成了连接“远程桌面”的工具),而对于Windows 9X/2000而言则必须另外安装终端访问工具。不难想象,并不是所有的客户机都已经安装了终端访问工具。这与我们所追求的“随时随地维护服务器”的目标并不相符。然而您知道吗?利用Windows Server 2003自带的“Web远程管理”服务,我们可以通过任何一台客户机的IE浏览器直接进行“远程桌面”连接,根本不需要终端访问工具。下面我们将简单谈谈该功能的使用方法。

一、安装Web远程管理
在Widows Server 2003中安装“IIS管理器”后Web远程管理并没有被默认安装,需要进行手动添加。依次打开“控制面板”→“添加和删除程序”→“添加/删除Windows组件”对话框,然后依次点击“Internet信息服务(IIS)”→“详细信息”→“万维网服务”→“详细信息”选项。在打开的“万维网服务”对话框中勾选“远程管理(HTML)”选项并依次点击“确定”→“下一步”→“完成”按钮完成安装。接着打开“Internet信息服务(IIS)管理器”对话框,

依次展开“hostname(本地计算机)”→“网站”目录。右键点击“Administration”选项→执行“属性”命令,打开“Administration属性”对话框。在该对话框的“网站”选项卡中点击“IP地址”右侧的下拉三角, 点选本机IP地址。最后点击“确定”按钮并关闭管理器窗口。
小提示:如果Windows Server 2003启用了防火墙,则必须开放“8098”端口。因为该端口是进行Web远程管理的默认端口。

二、进行“远程桌面”连接
假设客户机使用的是Windows 9X系统,我们在IE地址栏中键入如下地址“https://192.×.×.×:8098”,然后键入系统管理员的用户名和密码并回车即可登录Web远程管理界面。在打开的“服务管理”界面中,点击顶部主导航栏上的“维护”标签,然后点击“远程桌面”按钮。稍等片刻就会看到熟悉的Windows 2003登录对话框。用户名已经默认填写了登录Web远程管理时使用的系统管理员名称,只需键入密码并点击“确定”按钮即可连接到服务器的桌面了。经过在局域网环境中实际操作,使用相当流畅。
可见,只要有安装了IE浏览器的客户机,我们可以随时连接到“远程桌面”对服务器进行维护,真正实现了无障碍登录。
小提示:“远程桌面”功能只允许同时建立两个远程桌面会话,如果已经有两个会话正在运行,则新用户将被拒绝进行访问。
posted @ 2007-03-29 16:38 懒惰的车轮 阅读(759) | 评论 (0)编辑
打开注册表,
1.进入以下路径:
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Terminal Server\ Wds\rdpwd\Tds\tcp],看见PortNamber值了吗?其默认值是3389,修改成所希望的端口即可,例如6222。

2.再打开[HKEY_LOCAL_MACHINE\SYSTEM\CurrentContro1Set\Control\Tenninal Server\WinStations\RDP\Tcp],将PortNumber的值(默认是3389)修改成端口6222。

修改完毕,重新启动电脑,以后远程登录的时候使用端口6222就可以了。
posted @ 2007-03-29 16:31 懒惰的车轮 阅读(1851) | 评论 (0)编辑

引用类型是类型安全的指针,它们的内存是分配在堆(保存指针地址)上的。
String、数组、类、接口和委托都是引用类型。
强制类型转换与as类型转换的区别:当类型转换非法时,强制类型转换将抛出一个System.InvalidCastException异常,
而as不会抛出异常,它返回一个null值。
用using创建别名:using console = System.Console;
访问限定符:
public  该成员可以被其他任何类访问
protected 该成员只能被其派生类访问
private  该成员只能被本类的其他成员访问
internal 该成员只能在当前编译单元的其他成员访问
带参数列表和返回值的Main方法:
class Test
{
  public static int Main(string[] args)
  {
    foreach (string arg in args)
    {
    ...
    }
  }
}
构造函数(constructor)包括实例构造函数和静态构造函数。
构造函数与类名相同,且不能有返回值。例:
class TestClass
{
  TestClass()  //实例构造函数:可以访问静态成员和实例成员,用于初始化实例成员
  {
  ...
  }

  static TestClass() //静态构造函数:只能访问静态成员,用于初始化静态成员
  {
  ...
  }
}
类的静态成员属于类所有,不必生成实例就可以访问,它是在载入包含类的应用程序时创建的,
但静态方法不能访问类的实例变量和方法。通常,静态变量是在定义时就赋初始值的。
类的实例成员属于类的实例所有,不创建实例对象就无法对其进行访问,实例成员可以访问类的
静态成员和其它实例成员。
调用基类的析构函数:
class A
{
  public A()
  {
  ...
  }
}
class B
{
  public B(): base()  //调用基类的析构函数
  {
  ...
  }
}
常量:其值是在编译时设定的,必须是数值文字。默认状态下常量是静态的。例:
class A
{
  public const double pi = 3.1415;
}
常量是编译时就确定的值,只读字段是在运行才能确定的值。比如运行时才能确定的屏幕分辨率。
只读字段只能在类的析构函数中赋值。
静态只读字段:
class A
{
  public static readonly int ScreenWidth;  //静态只读字段
  static A()   //静态析构函数
  {
    ScreenWidth = 1024;  //在静态析构函数中初始化
  }
}
在类的继承中,类的析构函数是不会被继承的。
一个派生类只能从一个基类继承,不能同时从多个基类继承,但可以通过继承多个接口来
达到相同目的。实现多继承的唯一方法就是使用接口。例:
class MyFancyGrid: Control, ISerializable, IDataBound
{
...
}
密封类是不能继承的类,抽象类不能被定义为密封类,且密封类的私有成员不能用protected修饰,
只能用private。例:
sealed class A
{
...
}
关键字ref和out用于指定用引用方式传递方法的参数。
它们的区别是:ref参数必须初始化,而out参数不需要初始化。所以在方法处理代码依赖参数的
初始化值时使用ref,不依赖初始化值时使用out。
对out参数即使在传递前对其进行了初始化,其值也不会传递到方法处理函数内部。传递时系统
会将其设为未初始化。所以在方法内部必须对out参数进行初始化。
方法重载时,必须参数数目和参数类型其中之一不同,返回值不同不能作为重载。
C#不支持方法的默认值,只能通过方法重载来实现。例:
class A
{
  int Method(int a)
  {
  ...
  }

  void Method(int a, int b) //参数数目不同
  {    //返回值不同不能作为重载
  ...
  }
}
params参数用于一个不定数目参数的方法,一般后面跟一个数组。例:
class A
{
  public void Method(params int[] i)
  {
  ...
  }
}
方法的覆盖:指派生类覆盖基类的同名方法,有二种方法
1)第一种是在派生类要覆盖的方法前面加new修饰,而基类不需要作任何改动。
这种方法的缺点是不能实现多态。例:
class A
{
  public void Method()  //无需任何修饰
  {
  ...
  }
}

class B: A   //从基类继承
{
  new public void Method() //覆盖基类的同名方法
  {
  ...
  }
}

class TestClass
{
  A Instance = new B();
  Instance.Method();  //这时将调用类A的Method方法,而不是类B的Method方法
}

2)第二种是在派生类要覆盖的方法前面加override修饰,而基类的同名方法前面加virtual修饰。
这样就能实现多态,例:

class A
{
  virtual public void Method()   //基类定义虚方法
  {      //虚拟方法不能定义为private,因为private成员对派生类是无法访问的
  ...
  }
}

class B: A     //从基类继承
{
  override public void Method()   //派生类覆盖基类的同名虚方法
  {
  ...
  }
}

class TestClass
{
  protected void Test()
  {
    A Instance = new B();   //定义一个实例,类型为基类,从派生类创建
      //派生类总是能够向上转换为其基类
    Instance.Method();    //将调用派生类B的Method方法,而不是基类的,这就是多态
  }
}

说明:new修饰的方法覆盖不能实现多态的原因,是因为使用new时编译器只会实现早期绑定(early binding)。
即调用的方法在编译时就决定了:编译器看到Instance.Method()而Instance的类是A,就会调用类A的Method()方法。
override修饰的方法覆盖可以实现多态的原因,是因为实现了后期绑定(late binding)。
使用override时强制编译器在运行时根据类的真正类型正确调用相应的方法,而不是在编译时。
而基类的同名方法必须加virtual修饰。
类的静态方法可能通过 类名.静态方法名 这种格式来调用,不能使用 实例名.静态方法名 这种方法调用。
因为类的静态方法为类所有(是属于类本身的),而非实例所有(不是属于类的实例的)。
类的静态方法可以访问类的任何静态成员,但不能访问类的实例成员。
C#中类的变量称为字段。类的public变量称为类的公共字段。
类的属性由一个protected(也可以是private)字段和getter和setter方法构成:
class Address
{
  protected string zipCode; //protected字段,注意大小写
  public string ZipCode
  {
    get    //getter方法
    {
      return zipCode;
    }
    set    //setter方法
    {
      zipCode = value;  //被传递的值自动被在这个value变量中
    }
  };
}
只读属性是指省略setter方法的属性,只读属性只能读取,不能设置。
属性也可以用限定符virtual,override和abstract修饰,功能同其他类的方法。
属性有一个用处称为懒惰的初始化(lazy initialization)。即在需要类成员时才对它们进行
初始化。如果类中包含了很少被引用的成员,而这些成员的初始化又会花费大量的时候和系统
资源的话,懒惰的初始化就很有用了。
C#中数组对象共同的基类是System.Array。
将数组声明为类的一个成员时,声明数组与实例化数组必须分开,这是因为只能在运行时创建了
类的实例对象之后,才能实例化数组元素值。
声明:
int[] intArray;  //一维数组
int[,,] int3Array; //三维数组
初始化:
intArray = new int[3] {1,2,3};
int[,] int2Array = new int[2,3] {{1,2,3},{4,5,6}}; //声明时可以初始化
遍历:
1)一维数组
for (int i = 0; i < intArray.Length; i++); //Array.Length返回数组所有元素的个数
foreach (int i in intArray);
for (int i = 0; i < intArray.GetLength(0); i++);//Array.GetLength(0)返回数组第一维的个数
2)多维数组
for (int i = 0; i < int3Array.GetLength(0); i++) //遍历三维数组
  for (int j = 0; j < int3Array.GetLength(1); j++)
    for (int k = 0; k < int3Array.GetLength(2); k++)
    {
    ...
    }
数组的维数就是该数组的秩(Rank)。Array.Rank可以返回数据的秩。
锯齿数组(jagged Array)是元素为数组的数组,例:
int[][] jaggedArray = new int[2][]; //包含二个元素,每个元素是个数组
jaggedArray[0] = new int[2];  //每个元素必须初始化
jaggedArray[1] = new int[3];
for (int i = 0; i < jaggedArray.Length; i++) //遍历锯齿数组
  for (int j = 0; j < jaggedArray[i].Length; j++)
  {
  ...
  }
类的属性称为智能字段,类的索引器称为智能数组。由于类本身作数组使用,所以用
this作索引器的名称,索引器有索引参数值。例:
using System;
using System.Collections;
class MyListBox
{
  protected ArrayList data = new ArrayList();
  public object this[int idx]  //this作索引器名称,idx是索引参数
  {
    get
    {
      if (idx > -1 && idx < data.Count)
      {
        return data[idx];
      }
      else
      {
        return null;
      }
    }
    set
    {
      if (idx > -1 && idx < data.Count)
      {
        data[idx] = value;
      }
      else if (idx = data.Count)
      {
        data.Add(value);
      }
      else
      {
        //抛出一个异常
      }
    }
  }
}
接口是二段不同代码之间约定,通过约定实现彼此之间的相互访问。
C#并不支持多继承,但通过接口可实现相同功能。
当在接口中指定了实现这个接口的类时,我们就称这个类“实现了该接口”或“从接口继承”。
一个接口基本上就是一个抽象类,这个抽象类中除了声明C#类的其他成员类型——例如属性、
事件和索引器之外,只声明了纯虚拟方法。
接口中可以包含方法、属性、索引器和事件——其中任何一种都不是在接口自身中来实现的。例:
interface IExampleInterface
{
  //property declaration
  int testProperty { get; }

  //event declaration
  event testEvevnt Changed;

  //mothed declaration
  function void testMothed();

  //indexer declaration
  string this[int index] { get; set; }
}
说明:定义接口时,在方法、属性、事件和索引器所有这些接口成员都不能用public之类的访问限定符,
因为所有接口成员都是public类型的。
因为接口定义了一个约定,任何实现一个接口的类都必须定义那个接口中每一个成员,否则将编译失败。例:
using System;
public class FancyControl
{
  protected string data;
  public string Data
  {
    get {return this.data;}
    set {data = value;}
  }
}

interface IValidate
{
  bool Validate(); //接口方法
}

public class MyControl: FancyControl, IValidate
{
  public MyControl()
  {
    data = "my control data";
  }

  public bool Validate()  //实现接口
  {
    if (data == "my control data")
      return true;
    else
      return false;
  }
}
class InterfaceApp
{
  MyControl myControl = new MyControl();
 
  IValidate val = (IValidate)myControl;  //可以将一个实现某接口的类,转换成该接口
  bool success = val.Validate();  //然后可调用该接口的方法
}
也可以用:
bool success = myControl.Validate();
这种方法来调用Validate方法,因为Validate在类MyControl中是被定义成public的,如果去除public,Validate方法被隐藏,
就不能用这种方法调用了,这样隐藏接口方法称为名字隐藏(name hiding)。
可以用:类实例 is 接口名 来判断某个类是否实现了某接口,例:
myControl is IValidate  //MyControl类的实例myControl是否实现了IValidate接口
当然,也可用as来作转换,根据转换结果是否为null来判断某个类是否实现了某接口,例:
IValidate val = myControl as IValidate;
if (null == val)
{
...  //没有实现IValidate接口
}
else
{
...  //实现了IValidate接口
}

如果一个类从多个接口继承,而这些接口中如果定义的同名的方法,则实现接口的方法时,必须加接口名来区别,
写成 接口名.方法名。假设Test类从IDataStore和ISerializable二个接口继承,而这二个接口都有SaveData()方法,
实现SaveData()方法时必须写成:
class Test: ISerializable, IDataStore
{
  void ISerializable.SaveData()
  {
  ...
  }

  void IDataStore.SaveData()
  {
  ...
  }
}

如果一个类从多个接口继承,为了方便可以定义一个新的接口,这个接口继续多个接口,然后类直接从这个接口继承就
可以了,这个叫合并接口。例:
interface ISaveData: ISerializable, IDataStore
{  //不需要定义任何方法或成员,只是用作合并
}
class Test: ISaveData  //只要继承ISaveData就可以了
{
...
}
C# 操作符优先级(从高到低)
初级操作符 () x.y f(x) a[x] x++ x-- new typeof sizeof checked unchecked
一元操作符 + - | ~ ++x --x (T)x
乘除操作符 * / %
加减操作符 + -
位移操作符 << >>
关系操作符 < > <= >= is
等于操作符 ==
逻辑与  &
逻辑异或 ^
逻辑或  |
条件与  &&
条件或  ||
条件操作符 ?:
赋值操作符 = *= /= %= += -= <<= >>= &= ^= |=
所有的二元操作符除赋值符外都是左联合的,即从左到右计算。
typeof()运算符可以从一个类名得到一个System.Type对象,而从System.Object对象继承来的GetType()方法
则可从一个类实例来得到一个System.Type对象。例:
Type t1 = typeof(Apple); //Apple是一个类名
Apple apple = new Apple(); //apple是Apple类的一个实例
Type t2 = apple.GetType(); //t1与t2是相同的
通过反射得到一个类的所有成员和方法:
Type t = typeof(Apple);
string className = t.ToString(); //得到类名
MethodInfo[] methods = t.GetMethods(); //得到所有方法
foreach (MethodInfo method in methods)
{
//用method.ToString()得到方法名
}
MemberInfo[] members = t.GetMembers(); //得到所有成员
foreach (MemberInfo member in members)
{
//用member.ToString()得到成员名
}
sizeof()操作符用来计算值类型变量在内存中占用的字节数(Bytes),并且它只能在unsafe(非安全)
代码中使用。例:
static unsafe public void ShowSizes()
{
  int i, j;
  j = sizeof(short);
  j = sizeof(i);
}
尽可能使用复合赋值操作符,它比不用复合赋值操作符的效率高。
for语句的语法为:
for (initialization; Boolean-expression; step)
  embedded-statement
在initialization和step部份还可以使用逗号操作符,例:
for (int i = '0', j = 1; i <= '\xFF'; i++, j++)
for (int i = 1, j = 1; i < 1000; i += j, j = i - j) //输出斐波那契数列
 Console.Write("{0} ", i);
在switch语句中执行一个分支的代码后还想执行另一个分支的代码,可以用:
goto case 分支;
操作符重载是为了让程序更加自然,容易理解。想要为一个类重新定义一个操作符,使用以下语法:
public static 返回值 operator 操作符 (操作对象1[,操作对象2])
说明:
1)所有重载的操作符方法都必须定义为public和static
2)从技术上说返回值可以是任何类型,但通常是返回所定义方法使用的类型
3)操作对象的数目取决于重载是一元操作符还是二元操作符,一元操作符只要一个操作对象,二元操作符则需要二个。
4)不管重载是一元操作符还是二元操作符,第一个操作对象的类型都必须与返回值的类型一致;而对于二元操作符的第二个
操作对象的类型则可以是任何类型。
5)只有下列操作符可以被重载:
一元:+ - ! ~ ++ -- true false
二元:+ - * / % & | ^ << >> == != > < >= <=
赋值操作符(+=,-=,*-,/=,%=等等)无法被重载。
[]和()操作符也无法被重载。
6)操作符的优先级是无法改变的,运算优先级的规则是静态的。

例:假设一个Invoice发票类由多个InvoiceDetailLine类(成员只有一个Double类型的Amount金额属性)组成,
我们重载+操作符,使之可以将InvoiceDetailLine类的内容(注意不是金额合计)加在一起。
class Invoice
{
  public ArrayList DetailLine;
 
  public Invoice   //类的析构函数
  {
    DetailLine = new ArrayList(); //ArrayList存放多个InvoiceDetailLine类的实例
  }

  public static Invoice operator+ (Invoice Invoice1, Invoice Invoice2) //参数与返回值的类型一致
  {
    //Invoice1与Invoice2的内容合并
    Invoice ReturnInvoice = new Invoice();
    foreach(InvoiceDetailLine detailLine in Invoice1.DetailLines)
      ReturnInvoice.DetailLine.Add(detailLine);
    foreach(InvoiceDetailLine detailLine in Invoice2.DetailLines)
      ReturnInvoice.DetailLine.Add(detailLine);
    return ReturnInvoice;
  }
}

class InvoiceAddApp  //调用示例
{
  public static void main()
  {
    Invoice i1 = new Invoice();
    for(int i = 0; i < 3; i++)
      i1.DetailLine.Add(new InvoiceDetailLine(i + 1));

    Invoice i2 = new Invoice();
    for(int i = 0; i < 3; i++)
      i2.DetailLine.Add(new InvoiceDetailLine(i + 1));

    Invoice summaryInvoice = i1 + i2;  //调用重载的操作符+方法
  }
}


自定义类型转换可以编写代码实际二个不同的类、结构体之间的转换。
语法:public static implicite/explicite operator 输出类型 (输入类型)
说明:
1)转换方法必须是静态的。
2)implicite表示隐式转换,explicite表示显式转换。
3)输入类型和输出类型其中之一必须与包含转换的类或结构体类型。即转换必须与本类相关。
例:
struct Celisus
{
  public float t;

  public Celisus(float t)
  {
    this.t = t;   //this.t是结构体的字段,t是参数
  }

  public static implicite operator Celisus(float t) //float=>Celisus
  {
    return new Celisus(t);
  }

  public static implicite operator float(Celisus c) //Celisus=>float
  {
    return ((c.t - 32) / 9) * 5;
  }
}


代表的(delegate)目的与C++中的函数指针相同,代表不是在编译时被定义的,而是在运行时被定义的。
代表主要有二个用途:回调(Callback)和事件处理(event)
回调通常用于异步处理和自定义处理。例:
class DBManager
{
  static DBConnection[] activeConnections;
  //声明回调函数
  public void delegate EnumConnectionCallback(DBConnection connection);

  public static void EnumConnections(EnumConnectionCallback callback)
  {
    foreach (DBConnection connection in activeConnections)
    {
      callback(connection);  //执行回调函数
    }
  }
}

//调用
class DelegateApp
{
  public static void ActiveConncetionCallback(DBConnection connection) //处理函数
  {
  ...
  }

  public void main()
  {
    //创建指向具体处理函数的代表实例(新建一个代表,让它指向具体的处理函数)
    DBManager.EmnuConnectionCallback myCallback = new DBManager.EmnuConnectionCallback(ActiveConncetionCallback);
    DBManager.EnumConnections(myCallback);
  }
}

//使用静态代表,上面的调用改为
class DelegateApp
{
  //创建一个指向处理函数的静态代表
  public static DBManager.EmnuConnectionCallback myCallback
    = new DBManager.EmnuConnectionCallback(ActiveConncetionCallback);
  public static void ActiveConncetionCallback(DBConnection connection)
  {
  ...
  }

  public void main()
  {
    DBManager.EnumConnections(myCallback);
  }
}

//在需要时才创建代表,上面的调用改为
class DelegateApp
{
  //将创建代表放在属性的getter方法中
  public static DBManager.EmnuConnectionCallback myCallback
  {
    get
    {
      retun new DBManager.EmnuConnectionCallback(ActiveConncetionCallback);
    }
  }
  public static void ActiveConncetionCallback(DBConnection connection)
  {
  ...
  }

  public void main()
  {
    DelegateApp app = new DelegateApp(); //创建应用程序
    DBManager.EnumConnections(myCallback);
  }
}


可以将多个代表整合成单个代表,例:
class CompositeDelegateApp
{
  public static void LogEvent(Part part)
  {
  ...
  }

  public static void EmailPurchasingMgr(Part part)
  {
  ...
  }

  public static void Main()
  {
    //定义二个代表
    InventoryManager.OutOfStockExceptionMethod LogEventCallback
      = new InventoryManager.OutOfStockExceptionMethod(LogEvent);
    InventoryManager.OutOfStockExceptionMethod EmailPurchasingMgrCallback
      = new InventoryManager.OutOfStockExceptionMethod(EmailPurchasingMgr);
    //整合为一个代表,注意后加的代表先执行(这里是先执行LogEventCallback)
    InventoryManager.OutOfStockExceptionMethod onHandExceptionEventsCallback
      = EmailPurchasingMgrCallback + LogEventCallback;
    //调用代表
    InventoryManager mgr = new InventoryManager();
    mgr.ProcessInventory(onHandExceptionEventsCallback);
    //InventoryManager类的ProcessInventory方法的原型为:
    //public void ProcessInventory(OutOfStockExceptionMethod exception);
  }
}

可以根据需要将多个代表自由地组合成单个代表,例:
class CompositeDelegateApp
{
  //代表指向的处理函数(三个代表三个函数)
  public static void LogEvent(Part part)
  {
  ...
  }

  public static void EmailPurchasingMgr(Part part)
  {
  ...
  }

  public static void EmailStoreMgr(Part part)
  {
  ...
  }

  public static void Main()
  {
    //通过数组定义三个代表
    InventoryManager.OutOfStockExceptionMethod[] exceptionMethods
      = new InventoryManager.OutOfStockExceptionMethod[3];
    exceptionMethods[0] = new InventoryManager.OutOfStockExceptionMethod(LogEvent);
    exceptionMethods[1] = new InventoryManager.OutOfStockExceptionMethod(EmailPurchasingMgr);
    exceptionMethods[2] = new InventoryManager.OutOfStockExceptionMethod(EmailStoreMgr);

    int location = 1;
    //再定义一个代表(用于组合成单代表)
    InventoryManager.OutOfStockExceptionMethod compositeDelegate;
    //根据需要组合
    if (location = 2)
    {
      compositeDelegate = exceptionMethods[0] + exceptionMethods[1];
    }
    else
    {
      compositeDelegate = exceptionMethods[0] + exceptionMethods[2];
    }
    //调用代表
    InventoryManager mgr = new InventoryManager();
    mgr.ProcessInventory(compositeDelegate);
  }
}
C#的事件遵循“发布——预订”的设计模式。在这种模式中,一个类公布能够出现的所有事件,
然后任何的类都可以预订这些事件。一旦事件产生,运行环境就负责通知每个订户事件已经发生了。
当代表作为事件的处理结果时(或者说定义具有代表的事件),定义的代表必须指向二个参数的方法:
一个参数是引发事件的对象(发布者),另一个是事件信息对象(这个对象必须从EventArgs类中派生)。
例:
using System;

class InventoryChangeEventArgs: EventArgs //事件信息对象,从EventArgs类派生
{
... //假设定义二个public属性string Sku和int Change
}

class InventoryManager    //事件的发布者
{
  //声明代表
  public delegate void InventoryChangeEventHander(object source, InventoryChangeEventArgs e);
  //发布事件,event关键字可将一个代表指向多个处理函数
  public event InventoryChangeEventHandler onInventoryChangeHander;
 
  public void UpdateInventory(string sku, int change)
  {
    if (change == 0)
      return;
    InventoryChangeEventArgs e = new InventoryChangeEventArgs(sku, change);
    //触发事件
    if (onInventoryChangeHandler != null) //如果有预订者就触发
      onInventoryChangeHandler(this, e); //执行代表指向的处理函数
  }
}

class InventoryWatcher    //事件的预订者
{
  public InventoryWatcher(InventoryManager mgr) //mgr参数用于联结发布者
  {
    this.inventoryManager = mgr;
    //预订事件,用 += 调用多个处理函数
    mgr.onInventroyChangeHandler += new InventoryManager.InventoryChangeEventHandler(onInventoryChange);
    //事件处理函数
    void onInventroyChange(object source, InventroyChangeEventArgs e)
    {
    ...
    }

    InventoryManager inventoryManager;
  }
}

class EventsApp     //主程序
{
  public static void Main()
  {
    InventoryManager inventoryManager = new InventoryManager();
    InventoryWatcher inventoryWatcher = new InventoryWatcher(inventoryManager);

    inventoryManager.UpdateInventory("111 006 116", -2);
    inventoryManager.UpdateInventory("111 006 116", 5);
  }
}


Microsoft Windows NT和IBM OS/2等操作系统都支持占先型多任务。在占先型多任务执行中,处理器负责
给每个线程分配一定量的运行时间——一个时间片(timeslice)。处理器接着在不同的线程之间进行切换,
执行相应的处理。在单处理器的计算机上,并不能真正实现多个线程的同时运行,除非运行在多个处理器
的计算机上。操作系统调度的多线程只是根据分配给每个线程时间片进行切换执行,感觉上就像同时执行。

上下文切换(context switching)是线程运行的一部分,处理器使用一个硬件时间来判断一个指定线程的时间片
何时结束。当这个硬件计时器给出中断信号时,处理器把当前运行的线程所用的所有寄存器(registers)数据
存储到堆栈中。然后,处理器把堆栈里那些相同的寄存器信息存放到一种被称为“上下文结构”的数据结构中。
当处理器要切换回原来执行的线程时,它反向执行这个过程,利用与该线程相关的上下文结构,在寄存器里
重新恢复与这一线程相关的信息。这样的一个完整过程称为“上下文切换”。

多线程允许应用程序把任务分割为多个线程,它们彼此之间可以独立地工作,最大限度地利用了处理器时间。

using System;
using System.Threading;

class SimpleThreadApp
{
  public static void WorkerThreadMethod() //线程的执行体
  {
  ...      //执行一些操作
  }

  public static void Main()
  {
    //创建一个线程代表指向线程的执行体,ThreadStart是创建新线程必须用到的代表
    ThreadStart worker = new ThreadStart(WorkerThreadMethod);
    Thread t = new Thread(worker);  //用线程代表创建线程
    t.Start();     //执行线程
  }
}

可以通过两种方式来得到一个Thread对象:一种是通过创建一个新线程来得到,如上例;另一种在正在执行的线程调用
静态的Thread.CurrentThread方法。
静态方法Thread.Sleep(int ms)可以让当前线程(它自动调用Thread.CurrentThread)暂停指定毫秒的时间。
如果使用Thread.Sleep(0)那么当前线程将一直处于等待中,直到另一个线程调用这个线程的实例方法Thread.Interrupt方法,
等待才会结束。
使用Thread.Suspend方法也能挂起线程,Thread.Suspend方法可以被当前线程或其他线程调用,而Thread.Sleep(0)
只能由当前线程在执行体中调用。当线程用Thread.Suspend挂起时,必须用Thread.Resume方法恢复。不论Thread.Suspend
方法调用了多少次,只要调用Thread.Resume方法一次就可以线程恢复执行。用Thread.Suspend方法并不会阻塞线程,
调用立即返回。而Thread.Sleep(0)则会阻塞线程。所以确切地说Thread.Sleep(0)暂停线程,而不是挂起线程。
使用Thread.Abort方法可以终止正在执行的线程。当Thread.Abort方法被调用时,线程不会立即终止执行。运行环境将会
等待,直到线程到达文档中所描述的“安全点”。如果要确保线程已经完全停止,可以使用Thread.Join方法。这是一个同步
调用,同步调用意味着直到线程完全停止,调用才会返回。
Thread.Priority属性用于设置的线程的优先级。其值是Thread.ThreadPriority枚举值,可以设为Highest, AboveNormal,
Normal, BelowNormal, Lowest。缺省值是Thread.ThreadPriority.Normal。
线程的同步是为了解决多个线程同时使用同一对象产生的一些问题。通过同步,可以指定代码的临界区(critical section),
一次只有一个线程可以进入临界区。
使用System.Monitor类(锁定与信号量)进行线程同步:
using System;
using System.Threading;

public void SaveData(string text) //线程执行函数或线程执行函数调用的对象的方法
{
  ...   //执行其他一些不需要同步的处理

  Monitor.Enter(this); //获取对象的Monitor锁
  ...   //执行需要同步的处理
  Monitor.Exit(this); //释放对象的Monitor锁

  ...   //执行其他一些不需要同步的处理
}
说明:当执行Monitor.Enter方法时。这个方法会试图获取对象上的Monitor锁,如果另一个线程已经拥有了
这个锁,这个方法将会阻塞(block),直到这个锁被释放。
也可用C#的lock语句来获得和释放一个Monitor锁。上面同步写成:
public void SaveData(string text) //线程执行函数或线程执行函数调用的对象的方法
{
  ...   //执行其他一些不需要同步的处理

  lock(this)  //获取对象的Monitor锁,代码块执行完成后释放Monitor锁
  {
  ...   //执行需要同步的处理
  }

  ...   //执行其他一些不需要同步的处理
}

也可以使用System.Threading名称空间的Mutex类(互斥类)进行线程同步。与Monitor锁一样,一次只有一个线程
能获得一个给定的互斥。但Mutex要慢得多,但它增加了灵活性。例:
using System;
using System.Threading;
class Database
{
  Mutex mutex = new Mutex(false); //创建一个互斥,但不立即获得它
     //注意:创建互斥在需要同步的方法之外,实际上它只要创建一个实例
  public void SaveData(string text) //需要同步的方法
  {
    mutex.WaitOne();  //等待获得互斥
    ...    //需要同步的处理
    mntex.Close();  //释放互斥
  }
}

Mutex类重载了三个构造函数:
Mutex()       //创建并使创建类立即获得互斥
Mutex(bool initiallyOwned)    //创建时可指定是否要立即获得互斥
Mutex(bool initiallyOwned, string muterName)  //还可以指定互斥的名称
Mutex.WaitOne方法也重载了三次:
Mutex.WaitOne()      //一直等待
Mutex.WaitOne(TimeSpan time, bool exitContext)  //等待TimeSpan指定的时间
Mutex.WaitOne(int milliseconds, bool exitContext) //等待指定的毫秒
线程的用法:
1)并发操作:比如一个程序监视多个COM口,当每个COM接到信息时执行一段处理时。
2)复杂长时间操作:一个长时间的复杂操作可能会使界面停滞,停止用户响应,如果还允许用户停止它,
或者显示进度条、显示操作执行进程信息时。
反射(Reflection)就是能够在运行时查找类型信息,这是因为.NET编译的可执行(PE)文件中包括MSIL和元数据(metadata)。
反射的中心是类System.Type。System.Type是一个抽象类,代表公用类型系统(Common Type System, CTS)中的一种类型。
using System;
using System.Reflection; //反射命名空间,必须引用

public static void Main(string[] args)
{
  int i = 6;
  Type t = i.GetType();   //根据实例得到类型
  t = Type.GetType("System.Int32"); //根据类型的字符名称得到类型
}

通过Assembly类可以得到已经编译.NET Framework程序的中所有类型,例:
using System;
using System.Diagnostics;  //为了使用Process类
using System.Reflection;  //为了使用Assembly类

class GetTypesApp
{
  protected static string GetAssemblyName(string[] args)
  {
    string assemblyName;
    if (0 == args.Length) //如果参数为空,取当前进程的名称
    {
      Process p = Process.GetCurrentProcess();
      assemblyName = p.ProcessName + ".exe";
    }
    else
      assemblyName = args[0]; //取第一个参数,即当前运行程序名

    return assemblyName;
  }

  public static void Main(string[] args)
  {
    string assemblyName = GetAssemblyName(args);
    Assembly a = Assembly.LoadFrom(assemblyName); //调用编译程序集
    Type[] types = a.GetTypes();   //得到多个类型
    foreach (Type t in types)    //遍历类型数组
    {
    ...  //取得t.FullName,t.BaseType.FullName等类型信息
    }
  }
}
一个应用程序可以包括多个代码模块。若要将一个cs文件编译一个模块,只要执行下面的命令:
csc /target:module 要编译的模块.cs  //csc是C Sharp Compiler(C#编译器)
然后在应用程序中using编译的模块.cs中的NameSpace即可应用了。
要反射应用程序中所有代码模块(Module),只要:
Assembly a = Assembly.LoadFrom(assemblyName); //应用程序的物理文件名
Module[] modules = a.GetModules();
foreach(Module m in modules)
{
... //显示m.Name等
}
后期绑定(latebinding),例:
string[] fileNames = Directory.GetFiles(Environment.CurrentDirectory, "*.dll");
foreach (string fileName in fileNames)
{
  Assembly a = Assembly.LoadFrom(fileName);
  Type[] types = a.GetTypes();
  foreach(Type t in types)
  {
    if (t.IsSubclassOf(typeof(CommProtocol)))  //判断是否有CommProtocol的派生类
    {
      object o = Activator.CreateInstance(t);  //生成实例
      MethodInfo mi = t.GetMethod("DisplayName");
      mi.Invoke(o, null);    //调用方法
    }
  }
}
//带参数的例子
namespace Programming_CSharp
{
  using System;
  using System.Reflection;
 
  public class Tester
  {
    public static void Main( )
    {
      Type t = Type.GetType("System.Math");
      Object o = Activator.CreateInstance(t);

      // 定义参数类型
      Type[] paramTypes = new Type[1];
      paramTypes[0]= Type.GetType("System.Double");

      MethodInfo CosineInfo = t.GetMethod("Cos", paramTypes);

      //设置参数数据
      Object[] parameters = new Object[1];
      parameters[0] = 45;

      //执行方法
      Object returnVal = CosineInfo.Invoke(o, parameters);
      Console.WriteLine("The cosine of a 45 degree angle {0}", returnVal);
    }
  }
}
动态生成代码和动态调用的完整例子:
//动态生成代码的部分
using System;
using System.Reflection;
using System.Reflection.Emit;  //动态生成代码必须引用

namespace ILGenServer
{
  public class CodeGenerator
  {
    public CodeGenerator()
    {
      currentDomain = AppDomain.CurrentDomain;  //得到当前域
      assemblyName = new AssemblyName();  //从域创建一个程序集
      assemblyName.Name = "TempAssembly";
      //得到一个动态编译生成器,AssemblyBuilerAccess.Run表示只在内存中运行,不能保存
      assemblyBuilder = currentDomain.DefineDynamicAssembly(assemblyName, AssemblyBuilerAccess.Run);
      //从编译生成器得到一个模块生成器
      moduleBuilder = assemblyBuilder.DefineDynamicModule("TempModule");
      //模块生成器得到类生成器
      typeBuilder = moduleBuilder.DefineType("TempClass", TypeAttributes.Public);
      //为类添加一个方法
      methodBuilder = typeBuilder.DefineMethod("HelloWord", MethodAttributes.Public, null, null);
      //为方法写入代码,生成代码必须使用到IL生成器
      msil = methodBuilder.GetILGenerator();
      msil.EmitWriteLine("Hello World");
      msil.Emit(OpCodes.Ret);
      //最后还需要编译(build)一下类
      t = typeBuilder.CreateType();
    }
    AppDomain currentDomain;
    AssemblyName assemblyName;
    AssemblyBuilder assemblyBuilder;
    ModuleBuilder moduleBuilder;
    TypeBuilder typeBuilder;
    MethodBuilder methodBuilder;
    ILGenerator msil;
    object o;
    Type t;
    public Type T
    {
      get
      {
        return this.t;
      }
    }
  }
}
//动态调用的部分
using System;
using System.Reflection;
using ILGenServer;  //引用动态生成代码的类
public class ILGenClientApp
{
  public static void Main(
  {
    CodeGenerator gen = new CodeGenerator(); //创建动态生成类
    Type t = gen.T;
    if (null != t)
    {
      object o = Activator.CreateInstance(t);
      MethodInfo helloWorld = t.GetMethod("HelloWorld"); //为调用方法创建一个MethodInfo
      if (null != helloWorld)
      {
        helloWorld.Invoke(o, null);  //调用方法
      }
    }
  }
}
调用DLL
using System;
using System.Runtime.InteropServices; //为了使用DLLImport特性

class PInvokeApp
{
  [DllImport("user32.dll", CharSet=CharSet.Ansi)] //CharSet.Ansi指定Ansi版本的函数(MessageBoxA),CharSet.Unicode指定Unicode版本的函数(MessageBoxW)
  static extern int MessageBox(int hWnd, string msg, string caption, int type);  //声明DLL中的函数
 
  //[DllImport("user32.dll", EntryPoint="MessageBoxA")] //用这种方法使用不同的函数名
  //static extern int MsgBox(int hWnd, string msg, string caption, int type);
 
  //[DllImport("user32.dll", CharSet=CharSet.Unicode)]  //调用Unicode版的DLL函数
  //static extern int MessageBox(int hWnd, [MarshalAs(UnmanagedType.LPWStr)]string msg,
  // [MarshalAs(UnmanagedType.LPWStr)]string caption, int type); //将LPWStr翻译为string型,缺省情况系统只将LPStr翻译成string
  public static void Main()
  {
    MessageBox(0, "Hello, World!", "CaptionString", 0);  //调用DLL中的函数
  }
}
例2,使用回调:
class CallbackApp
{
  [DllImport("user32.dll")]
  static extern int GetWindowText(int hWnd, StringBuilder text, int count);

  delegate bool CallbackDef(int hWnd, int lParam);

  [DllImport("user32.dll")]
  static extern int EnumWindows(CallbackDef callback, int lParam);

  static bool PrintWindow(int hWnd, int lParam)
  {
    StringBuilder text = new StringBuilder(255);
    GetWindowText(hWnd, text, 255);
    Console.WriteLine("Window Caption: {0}", text);
    return true;
  }

  static void Main()
  {
    CallbackDef callback = new CallbackDef(PrintWindow);
    EnumWindows(callback, 0);
  }
}
关键字unsafe指定标记块在非控环境中运行。该关键字可以用于所有的方法,包括构造函数和属性,
甚至还有方法中的代码块。关键字fixed负责受控对象的固定(pinning)。Pinning是一种动作,向
垃圾收集器(Garbage Collector, GC)指定一些不能被移动的对象。为了不在内存中产生碎片,.NET
运行环境把对象四处移动,以便于最有效地利用内存。使用fixed后指定对象将不会被移动,所以就
可以用指针来访问它。
C#中只能得到值类型、数组和字符串的指针。在数组的情况下,第一个元素必须是值类型,因为C#
实际上是返回一个指向数组第一个元素的指针,而不是返回数组自身。
& 取一个变量的内存地址(即指向该变量的指针)
* 取指针所指变量的值
-> 取成员
例:
using System;
class UnsafeApp
{
  public static unsafe void GetValues(int* x, int* y)
  {
    *x = 6;
    *y = 42;
  }

  public static unsafe void Main()
  {
    int a = 1;
    int b = 2;
    GetValues(&a, &b);
  }
}
fixed语法为:fixed(type* ptr = expression) statements
其中type也可以为非控类型,也可是void;expression是任何产生一个type指针的表达式;
statements是应用的代码块。例:
fixed (int* f = &foo.x)  //foo是Foo类的一个实例,x是Foo类的一个int属性
{
  SetFooValue(f);  //SetFooValue方法的定义为unsafe static void SetFooValue(int* x)
}
传统的COM组件可以通过互操作层(COM Interop)与.NET运行环境交互。互操作层处理在托管运行环境和非托管区域
中的COM组件操作之间传递所有的消息。
要使COM组件能在.NET环境中使用,必须为COM组件生成元数据。.NET运行环境用元数据层业判断类型信息。在运行时刻
使用类型信息,以便生成RCW(Runtime Callable Wrapper,运行时可调用包装)。当.NET应用程序与COM对象交互时,
RCW处理对COM对象的装载和调用。RCW还完成许多其他的工作,如管理对象标识、对象生存周期以及接口缓冲区。
对象生存周期管理十分关键,因为.NET GC把对象到处移动,并且当对象不再使用时,自动处理这些对象。RCW服务告诉
.NET,应用程序正与托管.NET组件交互,同时又使非托管COM组件“觉得”COM对象是被传统的COM客户端调用的。
为了为COM组件生成元数据包装,必须使用tlbimp.exe(TypeLib Importer)工具:
tlbimp some_COM.tlb /out:som_COM.dll

原文:http://blog.csdn.net/fxyc2008/archive/2007/03/14/1529613.aspx

posted @ 2007-03-20 19:19 懒惰的车轮 阅读(61) | 评论 (0)编辑
1.制作一个bat/cmd为扩展名的文件.
2.输入要启动的应用程序:
start C:\"Program Files"\FlashGet\flashget.exe
-对于有空格的路径名要用引号
3.利用WINDOWS的任务计划来找到这个执行的cmd/bat文件,设定好日期和时间就OK了.
posted @ 2006-12-22 13:37 懒惰的车轮 阅读(205) | 评论 (1)编辑

In most cases, the GridView can automatically determine the proper data types of the columns you are updating. In the case of the page in Listing 5, the value retrieved from the ProductID textbox is automatically converted to an integer, and the value of the Discontinued checkbox is automatically converted to a BIT before the UPDATE command is executed (You can check this by executing the SQL Profiler tool while executing the page).

There are certain data types that the GridView will not automatically convert, however, such as Decimal columns. If you need to use a Decimal column, you'll need to explicitly specify the column data type within the SqlDataSource. The page in Listing  illustrates how to do this.

Listing Updating with Decimal Columns

<html>
<head runat="server">
    <title>Edit GridView with Decimal</title>
</head>
<body>
    <form id="Form1" runat="server">
    <asp:GridView  
        DataSourceID="ProductsSource"
        AutoGenerateEditButton="true"
        DataKeyNames="ProductID"
        Runat="Server" />
    
    <asp:SqlDataSource 
        ID="ProductsSource"
        ConnectionString=
          "Server=localhost;Database=Northwind;Trusted_Connection=true"
        SelectCommand=
        "SELECT ProductID,ProductName,UnitPrice,Discontinued 
         FROM Products"
        UpdateCommand=
          "Update Products 
            SET ProductName=@ProductName, UnitPrice=@UnitPrice,
            Discontinued=@Discontinued 
            WHERE ProductID=@ProductID"
            Runat="Server" >
            <UpdateParameters>
            <asp:Parameter Name="UnitPrice" Type="Decimal" />
            </UpdateParameters>
    </asp:SqlDataSource>
    </form>
</body>
</html>

Notice that the SqlDataSource control in Listing  now contains an <UpdateParameters> tag that lists the data type of the UnitPrice column. If you did not include this tag, the page would throw the SqlException "Disallowed implicit conversion from data type nvarchar to data type money."

posted @ 2005-08-19 11:47 懒惰的车轮 阅读(322) | 评论 (0)编辑

在使用MSBUILD 去编译vs 2005 方案或者项目的时候,如果这个方案或者项目的名称中间用空格符号,需要把这个方案或者项目整个用引号引起来,否则编译的时候会出错.

例如: Msbuild Handling LOB using ADONet.sln
这时候在控制台窗口会报错:
Microsoft (R) Build Engine Version 2.0.50215.312
[Microsoft .NET Framework, Version 2.0.50215.312]
Copyright (C) Microsoft Corporation 2005. All rights reserved.

MSBUILD : error MSB1008: Only one project can be specified.
Switch: LOB

For switch syntax, type "MSBuild /help"

正确的形式应该是这样的:msbuild "Handling LOB using ADONet.sln"
输出的结果如下:
Microsoft (R) Build Engine Version 2.0.50215.312
[Microsoft .NET Framework, Version 2.0.50215.312]
Copyright (C) Microsoft Corporation 2005. All rights reserved.

生成启动时间 2005-8-19 10:11:26。
__________________________________________________
项目“E:\Program Files\Net Framework 2.O Samples\Samples\Technologies\DataAccess
\Handling LOB using ADONet\CS\Handling LOB using ADONet.sln”(默认目标):

目标 Build:
    __________________________________________________
    项目“E:\Program Files\Net Framework 2.O Samples\Samples\Technologies\DataAc
cess\Handling LOB using ADONet\CS\Handling LOB using ADONet.sln”正在生成“E:\Pr
ogram Files\Net Framework 2.O Samples\Samples\Technologies\DataAccess\Handling L
OB using ADONet\CS\Handling LOB using ADONet.sln”(Handling LOB using ADONet 目
标):

    目标 Handling LOB using ADONet:
        __________________________________________________
        项目“E:\Program Files\Net Framework 2.O Samples\Samples\Technologies\Da
taAccess\Handling LOB using ADONet\CS\Handling LOB using ADONet.sln”正在生成“E
:\Program Files\Net Framework 2.O Samples\Samples\Technologies\DataAccess\Handli
ng LOB using ADONet\CS\Handling LOB using ADONet\Handling LOB using ADONet.cspro
j”(默认目标):

        目标 PrepareForBuild:
            正在创建目录“.\bin\Debug\”。
            正在创建目录“obj\Debug\”。
        目标 CoreResGen:
            正在将资源文件“Properties\Resources.resx”处理到“obj\Debug\Microso
ft.Samples.SqlServer.Properties.Resources.resources”中。
        目标 CompileRdlFiles:
            正在跳过目标“CompileRdlFiles”,原因是它没有输入。
        目标 CoreCompile:
            Csc.exe /noconfig /nowarn:"1701;1702" /warn:4 /define:DEBUG;TRACE /r
eference:D:\WINDOWS\Microsoft.NET\Framework\v2.0.50215\System.Data.dll /referenc
e:D:\WINDOWS\Microsoft.NET\Framework\v2.0.50215\System.dll /reference:D:\WINDOWS
\Microsoft.NET\Framework\v2.0.50215\System.Xml.dll /debug+ /debug:full /keyfile:
..\..\LOB.snk /optimize- /out:obj\Debug\handling_lob_using_adonet.exe /resource:
obj\Debug\Microsoft.Samples.SqlServer.Properties.Resources.resources /target:exe
 LargeObjectBinary.cs Program.cs Properties\AssemblyInfo.cs Properties\Resources
.cs Properties\Settings.cs
        目标 CopyAppConfigFile:
            正在跳过目标“CopyAppConfigFile”,原因是它没有输出。
        目标 CopyFilesToOutputDirectory:
            正在将文件从“obj\Debug\handling_lob_using_adonet.exe”复制到“.\bin
\Debug\handling_lob_using_adonet.exe”。
            Handling LOB using ADONet -> E:\Program Files\Net Framework 2.O Samp
les\Samples\Technologies\DataAccess\Handling LOB using ADONet\CS\Handling LOB us
ing ADONet\bin\Debug\handling_lob_using_adonet.exe
            正在将文件从“obj\Debug\handling_lob_using_adonet.pdb”复制到“.\bin
\Debug\handling_lob_using_adonet.pdb”。

生成成功。
    0 个警告
    0 个错误

已用时间 00:00:08.19

更多的使用请参考: MSbuild /?

posted @ 2005-08-19 10:19 懒惰的车轮 阅读(564) | 评论 (1)编辑
基本知识(版本号码的格式)

例如:oracle 10.0.1.1.2 
  
10:版本号
0:新特性版本号
1(第一个):维护版本号
1(第二个):普通的补丁设置号码
2:特殊的平台补丁设置号码
posted @ 2005-03-15 13:10 懒惰的车轮 阅读(550) | 评论 (0)编辑

OracleConnection con = new OracleConnection();
con.ConnectionString ="User Id=scott;Password=tiger;Data Source=";
DateTime startTime = DateTime.Now;
con.OpenWithNewPassword("one");
DateTime stopTime = DateTime.Now;
TimeSpan elapsedTime = stopTime - startTime;
Console.WriteLine(elapsedTime.TotalMilliseconds);
con.Close();
con.Dispose();
OracleConnection con2 = new OracleConnection();
con2.ConnectionString ="User Id=scott;Password=one;Data Source=";
startTime = DateTime.Now;
con2.OpenWithNewPassword("two");
stopTime = DateTime.Now;
elapsedTime = stopTime - startTime;
Console.WriteLine(elapsedTime.TotalMilliseconds);
Console.ReadLine();

Oracle ODP.Net Version:9.2.0.4
posted @ 2005-03-15 12:28 懒惰的车轮 阅读(457) | 评论 (0)编辑

//VB.Net

Dim dbConn as OracleConnection
dbConn = New OracleConnection(myConnectionString)
dbConn.Open()
Dim cmdProc As OracleCommand = New OracleCommand("myProcedureName", dbConn)
cmdProc.CommandType = CommandType.StoredProcedure
cmdProc.Parameters.Add(New OracleParameter("Param1", OracleDbType.NVarchar2)).Value = value1
cmdProc.Parameters.Add(New OracleParameter("Param2", OracleDbType.NVarchar2)).Value = value2
cmdProc.ExecuteNonQuery()

//C#
OracleConnection oracon=null;
oracon=new OracleConnection(myConnectionString);
oracon.Open();
OracleCommand oracmd=null;
oracmd=new OracleCommand("myProcedureName",oracon);
oracmd.CommandType=CommandType.StoreProcedure;

oracmd.Parameters.Add(new OracleParameter("Param1", OracleDbType.NVarchar2)).Value = value1;
oracmd.Parameters.Add(new OracleParameter("Param2", OracleDbType.NVarchar2)).Value = value2;
oracmd.ExecuteNonQuery();


Notes:
myConnectionString是连接数据库的连接字符串
myProcedureName 是数据库的存储过程

posted @ 2005-03-15 12:21 懒惰的车轮 阅读(472) | 评论 (0)编辑
Finally someone discovered the integrated help...

1) You have all the namespace imported properly? Add the Oracle.DataAccess.dll as reference?
2) Make sure you have only 1 version of ODP.NET help (check the Add/Remove Program). If not, remove all old version and reinstall ODP.NET
3) For VS.NET 2003, in the case where ODP.NET help is not registered (e.g. you don't see the book in the content section, search OracleXXX only returns MS's doc etc), do this:

Dynamic Help (press f1) -> Installing Help for Visual Studio -> Visual Studio .NET Combined Help Collection Manager -> check ODP.NET help and update. Restart studio.

----Operated Successfully!

This is a limitation of the help registration process for MSHelp2 system.
posted @ 2005-03-15 12:01 懒惰的车轮 阅读(687) | 评论 (0)编辑
 
Oracle新手最常碰到的6个错误及解决方案

  没有人会否认ORACLE是全球最有影响的数据库产品之一;不过好的东西似乎总不是那么好用(初看起来如此),甚至有些无情--总会给layman们一个个无情的错误号。下面是我个人的总结,条条有用,希望能给初学者一点启示。

  关于“好的东西似乎总不是那么好用(初看起来如此)”的一个笑话:在参加 IBM DB2 512、513培训前,在校园网上下载到了安装程序,不过任凭我们几个同学研究个半天,也不知哪个文件是安装文件,竟没有安装成功。最后,一致认为:看来这个培训真是太有必要了!事后,才知道--我们下载的是4linux的!

 [以8.1.6为例]:

1、ORA-12541:TNS:没有监听器

  原因:没有启动监听器或者监听器损坏。如果是前者,使用命令net start OracleOraHome81TNSListener(名字可能有出入)即可;如果是后者,则使用“Net8 Configuration Assistant”工具向导之“监听程序配置”增加一个监听器即可(基本不用写任何信息,一路OK。在添加之前可能需要把所有的监听器先删除!)

2、ORA-12500:TNS:监听程序无法启动专用服务器进程
  或
  ORA-12560:TNS:协议适配器错误

  原因:ORACLE的数据库服务没有启动。使用命令net start ORACLESERVICEORADB(ORADB为数据库名字)即可。如果仍没有解决,请继续向下看。

3、如果数据库服务启动失败,则很有可能是其注册表项值损坏,最好的做法是以下两步:

  1)ORADIM -DELETE -SID oradb 删除数据库服务项
  2)ORADIM -NEW -SID oradb 新增数据库服务项
  注:这个过程中如果出错,就重启计算机!

4、ORA-12154:TNS:能解析服务名

  原因:ORACLE的网络服务名没有正确配置。请使用“Net8 Configuration Assistant”工具向导之“本地网络服务名配置”配置TNS即可。如果仍没有解决,请继续向下看。

5、ORA-1034 :TNS:ORACLE不可用

  原因:ORACLE的数据库服务正确启动,但是数据库没有打开!

  使用命令:

  1)svrmgrl  启动服务管理器
  2)connect internal 以internal身份登陆
  3)startup  打开数据库

6、ORA-12560:TNS:协议适配器错误(顽固性的)

  原因:未知。

  解决:必杀技--打开“Windows任务管理器”,杀死ORACLE.exe及ORADIM.exe进程,书写自己的ora_startup.bat,执行之!

PS:

1、我的ora_startup.bat:

net start OracleOraHome81TNSListener
net start ORACLESERVICEORADB
svrmgrl 一般情况下不用,不过有时少不了它的,具体步骤见第5步。

2、我的ora_shutdown.bat:

net stop OracleOraHome81TNSListener
net stop ORACLESERVICEORADB

3、ORACLE相关服务名请参见“管理工具”之“服务”中以ORACLE开头的服务名。

posted @ 2005-03-15 11:58 懒惰的车轮 阅读(402) | 评论 (0)编辑
      Oracle Data Provider for .NET FAQ

--------------------------------------------------------------------------
    
      About ODP.NET
        a.. I am familiar with SQL Server's .NET data provider, but am new to Oracle. Is it easy to learn to use ODP.NET? (Last Updated: 12/27/04)

        b.. What are the different ways Oracle integrates with Microsoft .NET? (12/27/04)

        c.. Where can I find ODP.NET help and sample code? (12/12/03)

        d.. I have ODP.NET installed, but I can't find the ODP.NET Dynamic Help. Where is it? (12/12/03)

        e.. What are the new features in this version of ODP.NET? (12/27/04)

        f.. How do I make a feature enhancement request for ODP.NET? (12/04/02)

        g.. What features will ODP.NET support in future releases? (12/04/02)


      Configuration and Certification
        a.. Do I need to install ODP.NET on my Oracle DB server? (12/04/02)

        b.. Can ODP.NET work with Oracle8, Oracle8i, Oracle9i, and Oracle10g database (DB) servers? Can these DB servers be on Linux or Unix? (12/12/03)

        c.. Can ODP.NET be used with an Oracle8, Oracle8i, or Oracle9i Release 1 client? (11/02/04)

        d.. What do I need to have installed on my client machine to have ODP.NET work? (11/02/04)

        e.. Does ODP.NET support Windows Server 2003, .NET Framework 1.1, and Visual Studio .NET 2003? (11/02/04)

      Common Runtime Issues
        a.. How do I use distributed transactions with ODP.NET? (3/20/03)

        b.. What if I have some applications that require an earlier Oracle client (e.g. using the Microsoft OLE DB Provider for Oracle with Server Explorer)? I want to be able to run both ODP.NET and these other applications from the same machine. (12/12/03)

        c.. I get an error: "Unable to load DLL (OraOps.dll)". How do I fix this? (4/23/04)

        d.. I want to use the Oracle9i Release 2 version of OraMTS with an Oracle8i database. I get a "No error information available: XACT_E_NOENLIST(0x8004D00A)" error when running an application using OraMTS. (12/04/02)

      ODP.NET and Other Oracle Providers for .NET
        a.. Are ODP.NET and Microsoft .NET Framework Data Provider for Oracle the same product? (12/12/03)

        b.. Which .NET data access driver should I use among ODP.NET, Microsoft .NET Framework Data Provider for Oracle, OLE DB .NET, and ODBC .NET? (12/04/02)

        c.. I bundle ODP.NET with an application I've built, which I want to distribute or sell. Does Oracle charge licensing fees for this? (7/16/03)

    
      Q: I am familiar with SQL Server's .NET data provider, but am new to Oracle. Is it easy to learn to use ODP.NET?

      A: Yes. ODP.NET inherits from all the ADO.NET base classes, which is what SQL Server's .NET data provider, SqlClient, is based upon. The ADO.NET constructors, methods, and properties that you use with SQL Server will be the same with Oracle. For many applications, the only notable differences will be having all objects that were preceded with "Sql", such as SqlConnection, be preceded by "Oracle", such as OracleConnection, and accounting for differences between Oracle and SQL Server database data types, SQL, and stored procedure calls.

      Q: What are the different ways Oracle integrates with Microsoft .NET?

      A: Oracle integrates with .NET in a number of ways. For optimized .NET data access, ODP.NET enables access to all of the Oracle database's advanced features, such as RAC and XML DB, while ensuring the fastest performance from the .NET Framework.

      For .NET development tools that make Oracle easier to use, the Oracle Developer Tools for Visual Studio .NET provide wizards and designers that auto-generate ODP.NET code and can browse and edit schemas and stored procedures. Additionally, it includes a Data Window to modify and view data and context-sensitive help.

      For application integration, web services can facilitate integration between your existing Oracle and .NET applications.

      Q: Where can I find ODP.NET help and sample code?

      A: ODP.NET documentation is available from within Visual Studio .NET using Dynamic Help. Just hit the F1 key when your cursor is on an ODP.NET API and a help page for that API will appear right within Visual Studio .NET.

      Additional ODP.NET documentation is available both locally installed and from the ODP.NET documentation page.

      Sample code can be found both locally as part of the ODP.NET installation (e.g. c:\oracle\<Oracle Home Name>\ODP.NET\samples) and on ODP.NET samples page.

      ODP.NET users can ask questions on the ODP.NET discussion forum.

      Q: I have ODP.NET installed, but I can't find the ODP.NET Dynamic Help.  Where is it?

      A: This behavior sometimes occurs when installing new Visual Studio .NET versions over an ODP.NET installation.  To enable ODP.NET Dynamic Help, go to Visual Studio .NET Combined Help Collection Manager located in Visual Studio .NET 2002 or Visual Studio .NET 2003. Make sure the box next to the Oracle Data Provider for .NET Help is checked and click on the Update VSCC button.  Close Visual Studio .NET and re-open it to enable ODP.NET Dynamic Help.

      Q: What are the new features in this version of ODP.NET?

      A:

      ODP.NET 10.1.0.3.0

      a.. Statement caching
      a.. DeriveParameters - automatic population of stored procedure parameters
      a.. Cancel long running queries
      a.. ADO.Net 1.1 interfaces - HasRows and EnlistDistributedTransaction properties
      a.. LOB and LONG retrieval - Entire LOB and LONG column data can be retrieved even if the select list does not contain a primary key, ROWID, or unique key.
      ODP.NET 10.1.0.2.0

      a.. Grid support
      a.. Schema-based XMLType
      a.. BINARY_FLOAT and BINARY_DOUBLE datatypes
      a.. Multiple Oracle Homes
      ODP.NET 9.2.0.4.01

      a.. Improved XML DB and XMLType support
      a.. PL/SQL associative arrays
      a.. connection pool validation
      a.. InitialLOBFetchSize property to improve LOB retrieval performance

      Q: How do I make a feature enhancement request for ODP.NET?

      A: You can contact Oracle Support or use the ODP.NET discussion forum to make an enhancement request.

      Q: What features will ODP.NET support in future releases?

      A: In general, Oracle does not discuss features in future product releases until the release date nears. We are well aware of enhancement requests made through the ODP.NET discussion forum and Oracle support. We encourage Oracle users to continue to make their requests known. Oracle will do its best to fulfill these requests in future releases.

      Q: Do I need to install ODP.NET on my Oracle DB server?

      A: No. You only need to install ODP.NET on your client or middle-tier machine, wherever you use the .NET Framework.

      Q: Can ODP.NET work with Oracle8, Oracle8i, Oracle9i, and Oracle10g database (DB) servers? Can these DB servers be on Linux or Unix?

      A: Yes and yes, but you will need to use an Oracle9i Release 2 client or higher on the same Windows machine you are using ODP.NET from.

      Q: Can ODP.NET be used with an Oracle8, Oracle8i, or Oracle9i Release 1 client?

      A: No. You need to use the Oracle9i Release 2 or higher client.

      Q: What do I need to have installed on my client machine to have ODP.NET work?

      A: You will require the following:

      a.. Windows 2000, Windows XP Professional, or Windows Server 2003
      a.. Microsoft .NET Framework 1.0 or higher
      a.. Oracle9i Client Release 2 (9.2) or higher
      a.. Oracle Net Services (included with the client)
      a.. Oracle Services for Microsoft Transaction Server, Release 2 (9.2) or higher. This is required for applications using Enterprise Services transacations.

      Q: Does ODP.NET support Windows Server 2003, .NET Framework 1.1, and Visual Studio .NET 2003?

      A: Yes, ODP.NET 9.2.0.2.102 and higher supports 32-bit Windows Server 2003, .NET Framework 1.0 and higher, and Visual Studio .NET 2002 and higher.

      Q: How do I use distributed transactions with ODP.NET?

      A: The Oracle Services for MTS (OraMTS) is required for distributed transaction support with COM+/Enterprise Services/Microsoft Transaction Server. OraMTS is available to download for free on OTN.

      Q: What if I have some applications that require an earlier Oracle client (e.g. using the Microsoft OLE DB Provider for Oracle with Server Explorer)? I want to be able to run both ODP.NET and these other applications from the same machine.

      A: To accomplish this, do the following:

      Installation
      Ensure that when you install the new Oracle client that you don't overwrite your older Oracle Home. On the second installation screen (File Locations) of your Oracle client install, create a directory different from your older Oracle client installation.

      You will now have two Oracle Homes: one for your older Oracle client and one for ODP.NET. The last Oracle Home you installed will always be the client your .NET applications will use. For example, if you installed the Oracle9i Release 2 client last, this will be the client version all applications on your system will use.

      Switching between Oracle Homes
      You can switch between the different Oracle clients on your machine by using the Oracle Home Selector. The Oracle Home Selector changes your System Path settings so that the Oracle client you specify is the one used by applications on your system.

      Q:I get an error: "Unable to load DLL (OraOps.dll)". How do I fix this?

      A: First, ensure the OraOps.dll file is in your Oracle bin directory (e.g. d:\oracle\ora92\bin\). Next, check that your Oracle bin directory is in the Windows system path. If either of these are not present, re-install ODP.NET. Depending on the application, you may have to restart the application (e.g. Windows Service) or reboot the computer (e.g. ODP.NET install makes changes to the PATH) for ODP.NET installation to be complete. If your ODP.NET installation is still not working, you may be running into this problem.

      Q: I want to use the Oracle9i Release 2 version of OraMTS with an Oracle8i database. I get a "No error information available: XACT_E_NOENLIST(0x8004D00A)" error when running an application using OraMTS.

      A: These are two known issues with OraMTS. These problems can be resolved if you upgrade to OraMTS version 9.2.0.1.1 or higher.

      Q: Are ODP.NET and Microsoft .NET Framework Data Provider for Oracle the same product?

      A: No, these are two separate products. Both provide data access to the Oracle database. However, ODP.NET is developed by Oracle and provides more functionality and faster performance than the Microsoft .NET Framework Data Provider for Oracle. Oracle recommends you use ODP.NET.

      Q: Which .NET data access driver should I use among ODP.NET, Microsoft .NET Framework Data Provider for Oracle, OLE DB .NET, and ODBC .NET?

      A: ODP.NET offers more functionality and better performance over the Microsoft .NET Framework Data Provider for Oracle, OLE DB .NET, and OLE DB .NET.

      Q: I bundle ODP.NET with an application I've built, which I want to distribute or sell. Does Oracle charge licensing fees for this?

      A: In most cases, Oracle does not charge any fees for distributing the Oracle client nor ODP.NET with a third-party application. However, it is best to consult the licensing agreement from which you acquired rights to the Oracle software. If you purchased Oracle licenses directly from Oracle, consult your Oracle licensing contract or your Oracle sales representative. If you downloaded ODP.NET from OTN, consult the licensing agreement that you agreed to prior to downloading the software.
    


Using Oracle Database Transactions in .NET
by Jason Price

Learn the basics about coding database transactions in Visual Basic .NET and C#.

      Downloads for this article:
      · Sample code
      · ODP.NET
      · Oracle Database 10g
      · Microsoft .NET Framework and SDK 



In this article, you will learn how to use database transactions in Visual Basic .NET (VB.NET) and Visual C# .NET (C#). Specifically, you will explore database transactions, use OracleTransaction objects in .NET programs, and learn how to set a transaction savepoint. All the scripts and files referenced in this article are available here. This article assumes familiarity with C# and VB.NET programming in general.

Required Software

Before you can follow along with the examples shown in this article, you will need to install the following software:

  a.. Windows NT 4.0, Windows 2000, Windows XP Professional, or Windows Server 2003
  b.. Access to an installation of the Oracle database (Oracle8i release 3 8.1.7 or later)
  c.. Oracle Client (version 10.1.0.2.0 or later)
  d.. Oracle Net (version 10.1.0.2.0 or later)
  e.. Oracle Data Providers for .NET (version 10.1.0.2.0 or later)
  f.. Microsoft .NET Framework (version 1.0 or later)
  g.. Microsoft .NET Framework SDK (version 1.0 or later)
If you intend to develop and run applications using Enterprise Services transactions or distributed transactions then you will also need to install Oracle Services for Microsoft Transaction Server (10.1.0.2.0 or later).

You will need to download and install the .NET Framework as well as the SDK separately, and install the framework first. You will also need to download and install Oracle Database 10g, which includes Oracle Data Provider for .NET (ODP.NET). You can choose to install ODP.NET and the database server on separate machines or the same machine.

Note: The ODP.NET drivers are tuned for maximum performance when accessing an Oracle database, and also support the rich features of an Oracle database such as the BFILE, BLOB, CLOB, XMLType, and so on. If you are developing .NET applications running against an Oracle database, ODP.NET is your best data access solution for both features and performance.

Database Schema Setup

First you need to set up your database schema, which is a simplified example of a web store. You must first create a user named store and grant the required privileges to that user as follows (you must first log into the database as user with the CREATE USER privilege to create a user):

CREATE USER store IDENTIFIED BY store;
GRANT connect, resource TO store;Note: You will find the two previous statements and the others shown in this section to set up the store schema in the source code file db1.sql.

The next two statements connect as the store user:

CONNECT store/store;The following statements create the four required database tables named product_types and products:

CREATE TABLE product_types (
  product_type_id INTEGER
    CONSTRAINT product_types_pk PRIMARY KEY,
  name VARCHAR2(10) NOT NULL
);

CREATE TABLE products (
  product_id INTEGER
    CONSTRAINT products_pk PRIMARY KEY,
  product_type_id INTEGER
    CONSTRAINT products_fk_product_types
    REFERENCES product_types(product_type_id),
  name VARCHAR2(30) NOT NULL,
  description VARCHAR2(50),
  price NUMBER(5, 2)
);Note: If you create the tables in a different schema to store, you will need change the schema name in the sample configuration files that you will see later.

The product_types table is used to store the names of the product types that may be stocked by an example online store, and the products table contains detailed information about the products sold.

The following INSERT statements add rows to the product_types and products tables:

INSERT INTO product_types (
  product_type_id, name
) VALUES (
  1, 'Book'
);
INSERT INTO product_types (
  product_type_id, name
) VALUES (
  2, 'DVD'
);

INSERT INTO products (
  product_id, product_type_id, name, description, price
) VALUES (
  1, 1, 'Modern Science', 'A description of modern science', 19.95
);
INSERT INTO products (
  product_id, product_type_id, name, description, price
) VALUES (
  2, 1, 'Chemistry', 'Introduction to Chemistry', 30.00
);
INSERT INTO products (
  product_id, product_type_id, name, description, price
) VALUES (
  3, 2, 'Supernova', 'A star explodes', 25.99
);
INSERT INTO products (
  product_id, product_type_id, name, description, price
) VALUES (
  4, 2, 'Tank War', 'Action movie about a future war', 13.95
);

COMMIT;Next, you will learn about database transactions.

Introducing Database Transactions

A database transaction is a group of SQL statements that are a logical unit of work. You can think of a transaction as an inseparable set of SQL statements that should be made permanent in the database (or undone) as a whole. An example would be a transfer of money between bank accounts: One UPDATE statement would subtract from the total amount of money from one account, and another UPDATE would add money to the other account. Both the subtraction and the addition must either be permanently recorded in the database, or they both must be undone—otherwise money will be lost. This simple example uses only two UPDATE statements, but a more realistic transaction may consist of many INSERT, UPDATE, and DELETE statements.

To permanently record the results of the SQL statements in a transaction, you perform a commit with the COMMIT statement. To undo the results of the SQL statements, you perform a rollback with the ROLLBACK statement, which resets all the rows back to what they were originally. Any changes you make prior to performing a rollback will be undone, as long as you haven't disconnected from the database beforehand. You can also set a savepoint that may be used to rollback a transaction to a specific point, while leaving the other statements in the transaction intact.

Using Database Transactions in C# and VB.NET

You may use an object of the OracleTransaction class to represent a transaction. Two of the properties of the OracleTransaction class include Connection, which specifies the database connection associated with the transaction, and IsolationLevel, which specifies the transaction isolation level; you will learn more about transaction isolation levels later in this article.

The OracleTransaction class contains a number of methods to control a transaction. You use the Commit() method to permanently commit your SQL statements, and you use Rollback() to undo them. You may also use Save() to set a savepoint in a transaction.

I will now walk you through the steps in two example programs, one written in C# (TransExample1.cs) and the other in VB.NET (TransExample1.vb). These programs illustrate how to execute a transaction that contains two INSERT statements. The first INSERT will add a row to the product_types table, and the second will add a row to the products table.

Importing the Namespaces

The following C# program statements specify that the System and Oracle.DataAcess.Client namespaces are used in the program:

using System;
using Oracle.DataAccess.Client;Here are the equivalent VB.NET statements:

Imports System
Imports Oracle.DataAccess.ClientThe Oracle.DataAccess.Client namespace forms part of ODP.NET, and contains the OracleConnection, OracleCommand, and OracleTransaction classes, among many others. These classes are used in the example programs.

Step 1

The first step is to create an OracleConnection object to connect to the Oracle database and then open the connection.

In C#:

OracleConnection myOracleConnection =
  new OracleConnection(
    "User Id=store;Password=store;Data Source=ORCL"
  );
myOracleConnection.Open();In VB.NET:

Dim myOracleConnection As New OracleConnection( _
  "User Id=store;Password=store;Data Source=ORCL")
myOracleConnection.Open()The User Id and Password attributes specify the database user and password of the schema you want to connect to. The Data Source attribute specifies the Oracle Net service name for the database; the default service name for starter database is ORCL. If you are using a different database from the starter or your service name is different, then you will need to change the setting for the Data Source attribute in your program.

Step 2

The second step is to create an OracleTransaction object and start the transaction by calling the BeginTransaction() method of the OracleConnection object.

In C#:

OracleTransaction myOracleTransaction =
  myOracleConnection.BeginTransaction();In VB.NET:

Dim myOracleTransaction As OracleTransaction = _
  myOracleConnection.BeginTransaction()Step 3

The third step is to create an OracleCommand object to store a SQL statement.

In C#:

OracleCommand myOracleCommand = myOracleConnection.CreateCommand();In VB.NET:

Dim myOracleCommand As OracleCommand =
  myOracleConnection.CreateCommandBecause the OracleCommand object was created using the CreateCommand() method of the OracleConnection object, it automatically uses the transaction for the OracleConnection object set in Step 2.

Step 4

The fourth step is to set the CommandText property of the OracleCommand object to the first INSERT statement that adds a row to the product_types table.

In C#:

myOracleCommand.CommandText =
  "INSERT INTO product_types (" +
  "  product_type_id, name" +
  ") VALUES (" +
  "  3, 'Magazine'" +
  ")";
In VB.NET:

myOracleCommand.CommandText = _
  "INSERT INTO product_types (" & _
  "  product_type_id, name" & _
  ") VALUES (" & _
  "  3, 'Magazine'" & _
  ")"Step 5

The fifth step is to run the INSERT statement using the ExecuteNonQuery() method of the OracleCommand object.

In C#:

myOracleCommand.ExecuteNonQuery();
In VB.NET:

myOracleCommand.ExecuteNonQuery()
Steps 6 and 7

The sixth and seventh steps are to set the CommandText property of the OracleCommand object to the second INSERT statement that adds a row to the products table and run it.

In C#:


myOracleCommand.CommandText =
  "INSERT INTO products (" +
  "  product_id, product_type_id, name, description, price" +
  ") VALUES (" +
  "  5, 3, 'Oracle Magazine', 'Magazine about Oracle', 4.99" +
  ")";
myOracleCommand.ExecuteNonQuery();In VB.NET:

myOracleCommand.CommandText = _
  "INSERT INTO products (" & _
  "  product_id, product_type_id, name, description, price" & _
  ") VALUES (" & _
  "  5, 3, 'Oracle Magazine', 'Magazine about Oracle', 4.99" & _
  ")"
myOracleCommand.ExecuteNonQuery()
Step 8

The eighth step is to commit the transaction in the database using the Commit() method of the OracleTransaction object.

In C#:


myOracleTransaction.Commit();
In VB.NET:


myOracleTransaction.Commit()
After the Commit() method has completed, the two new rows added by the INSERT statements will be made permanent in the database.

Step 9

The ninth step is to close the OracleConnection object using the Close() method.

In C#:


myOracleConnection.Close();
In VB.NET:


myOracleConnection.Close()
Compiling and Running the Example Programs

To compile the example C# program, you may use the csc command to run the C# compiler. Because the program uses the Oracle Data Access DLL, you use the /r option to specify the full path to that DLL; for example:


 
csc TransExample1.cs /r:C:\oracle\product\10.1.0\
  Client_1\bin\Oracle.DataAccess.dll
Note: You will need to replace the path to the DLL with the appropriate one for your computer. Also, if your computer cannot find the csc compiler, you may need to run the Microsoft sdkvars.bat script to first set the environment variables for the .NET SDK; you will find that script in the bin directory where you installed the .NET SDK.

If you get the following error:


Example1.cs(10,7): error CS0246: The type or namespace name 'Oracle'
could not be found (are you missing a using directive or an assembly reference?)
you haven't correctly specified the Oracle Data Access DLL in your compilation command. (See John Paul Cook's Technical Article "Building a .NET Application on the Oracle Database" for setup information.)

Here is the equivalent command for compiling the VB.NET program:


vbc TransExample1.vb /r:C:\oracle\product\10.1.0\
  Client_1\bin\Oracle.DataAccess.dll /r:system.dll /r:system.data.dll
Next, to run the example you enter the following:


TransExample1
You should see the output from the program. If, however, you get an exception similar to the following:


An exception was thrown
Message = ORA-12514: TNS:listener does not currently know
  of service requested in connect descriptor
your setting for the Data Source in the connection string to the OracleConnection object is incorrect. You should speak with your DBA or consult the Oracle Net documentation for further details.

If you are using VS .NET, you can do the following to compile and run the C# program TransExample1.cs:

  1.. Create a new C# console application. File>New Project, then pick Visual C# Projects, Console Application.
  2.. Name the project TransExample1.
  3.. Replace all the code generated by VS .NET with the code in TransExample1.cs.
  4.. Add a reference to the Oracle.DataAccess.dll by selecting Project>Add Reference, then browse to the directory where you installed ODP.NET (on my machine it is in C:\oracle\product\10.1.0\Client_1\bin\Oracle.DataAccess.dll), and then double-click on Oracle.DataAccess.dll.
  5.. MRun the program by selecting Debug>Start without Debugging.
To compile and run TransExample1.vb you perform a similar set of steps, except that you pick a Visual Basic console application in Step 1 and you replace the generated code with the code in TransExample1.vb at Step 3.

Checking the Results of the Program

When you've run the C# or VB .NET program, you can check the results of the transaction using the following SELECT statement in SQL*Plus:
SELECT p.product_id, p.product_type_id, pt. name, p.name, p.description, p.price
FROM products p, product_types pt
WHERE p.product_type_id = pt.product_type_id
AND p.product_id = 5;
You will see the following result:
PRODUCT_ID PRODUCT_TYPE_ID NAME       NAME
---------- --------------- ---------- -----------------------
DESCRIPTION                                             PRICE
-------------------------------------------------- ----------
         5               3 Magazine   Oracle Magazine
Magazine about Oracle                                    4.99
Next, you will learn how to set a transaction savepoint.

Setting a Transaction Savepoint in a .NET Program

As mentioned earlier in this article, you can set a savepoint that may be used to rollback a transaction to a specific point, while leaving the other statements in the transaction intact. You use the Save() method of the OracleTransaction class to set a savepoint in a transaction.

You might want to use a savepoint if you have a very long transaction and you want to have the ability to rollback only to a specific point. For example, you might want to make some changes to 10 products, then set a savepoint, and then make changes to 10 more products; if you make a mistake in the second batch of changes, you can rollback to the savepoint and keep your first batch of changes intact.

I will now walk you through the relevant new steps in example C# (TransExample2.cs) and VB.NET (TransExample2.vb) programs that illustrate how to use a savepoint. The programs add a row to the products table, sets a savepoint, adds another row to the products table, performs a rollback to the savepoint, and then reads the rows from the products table. Only the first row added to the products table will remain after the rollback to the savepoint: the second row will have been removed.

Steps 1 to 3 are the same as those shown in the section "Using Database Transactions in C# and VB.NET" and are therefore omitted here.

Step 4

The fourth step adds a row to the products table with a product ID of 6.

In C#:

myOracleCommand.CommandText =
  "INSERT INTO products (" +
  "  product_id, product_type_id, name, description, price" +
  ") VALUES (" +
  "  6, 2, 'Man from Another World', 'Man from Venus lands on Earth', 24.99" +
  ")";
myOracleCommand.ExecuteNonQuery();
In VB.NET:

myOracleCommand.CommandText = _
  "INSERT INTO products (" & _
  "  product_id, product_type_id, name, description, price" & _
  ") VALUES (" & _
  "  6, 2, 'Man from Another World', 'Man from Venus lands on Earth', 24.99" & _
  ")"
myOracleCommand.ExecuteNonQuery()
Step 5

The fifth step sets a savepoint named SaveProduct using the Save() method of the OracleTransaction object.

In C#:

myOracleTransaction.Save("SaveProduct");
In VB.NET:

myOracleTransaction.Save("SaveProduct")
Step 6

The sixth step adds another row to the products table with a product ID of 7.

In C#:

myOracleCommand.CommandText =
  "INSERT INTO products (" +
  "  product_id, product_type_id, name, description, price" +
  ") VALUES (" +
  "  7, 2, 'Z-Files', 'Mysterious stories', 14.99" +
  ")";
myOracleCommand.ExecuteNonQuery();
In VB.NET:

myOracleCommand.CommandText = _
  "INSERT INTO products (" & _
  "  product_id, product_type_id, name, description, price" & _
  ") VALUES (" & _
  "  7, 2, 'Z-Files', 'Mysterious stories', 14.99" & _
  ")"
myOracleCommand.ExecuteNonQuery()
Step 7

The seventh step performs a rollback to the SaveProduct savepoint previously set in Step 5.

In C#:

myOracleTransaction.Rollback("SaveProduct");
In VB.NET:

myOracleTransaction.Rollback("SaveProduct")
After the rollback is complete, the second row added in Step 6 is removed, but the first row added in Step 4 remains.

The remaining steps in TransExample2.cs and TransExample2.vb display the contents of the products table, rollback the entire transaction, and disconnect from the database.

A Quick Note on Oracle Transaction Services for Microsoft Transaction Server

Microsoft Transaction Server is a proprietary transaction processing system that runs on an internet or network server. Microsoft Transaction Server deploys and manages application and database transaction requests on behalf of a client computer.


Microsoft Transaction Server is a component of the three-tiered, server-centric architecture model. This approach enables the presentation, business logic, and data elements of applications to be clearly separated onto different computers connected in a network. Without any special integration, you can deploy a component in Microsoft Transaction Server that connects to an Oracle Database server release 8.0.6 or later; but first you must install Oracle Services for Microsoft Transaction Server.

Conclusion

In this article you explored using database transactions in .NET programs. You saw how to create OracleTransaction objects and use them to submit transactions to the database, how to use a savepoint to partially roll back a transaction, and how the Oracle Database separates concurrent transactions.


--------------------------------------------------------------------------------
Technical consultant and writer Jason Price is a Microsoft Certified Professional and an Oracle Certified Database Administrator and Application Developer with over 10 years of experience in the software industry. He is the author of Oracle Database 10g SQL (McGraw-Hill/Osborne, 2004), Mastering C# Database Programming (Sybex, 2004), Mastering Visual C# .NET Programming (Sybex, 2003), Oracle9i JDBC Programming (McGraw-Hill/Osborne, 2002), and Java Programming with Oracle SQLJ (O'Reilly, 2001).
posted @ 2005-03-15 11:56 懒惰的车轮 阅读(1281) | 评论 (0)编辑

web service

Basics
http://msdn.microsoft.com/webservices/understanding/webservicebasics/default.aspx
---
XML Web Services Created Using ASP.NET and XML Web Service Clients
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpguide/html/cpconaspnetbuildingwebservicesaspnetwebserviceclients.asp

Declaring an XML Web Service
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpguide/html/cpconDeclaringWebService.asp
(reference:@ WebService Directive in XML Web Services
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpgenref/html/gnconWebServiceDirectiveSyntax.asp)

Using the WebMethod Attribute
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vbcon/html/vbtskUsingWebMethodAttribute.asp
---
Using SOAP Extensions in ASP.NET
http://msdn.microsoft.com/msdnmag/issues/04/03/ASPColumn/

Altering the SOAP Message Using SOAP Extensions
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpguide/html/cpconalteringsoapmessageusingsoapextensions.asp
---
Asynchronous Web Service Calls over HTTP with the .NET Framework
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnservice/html/service09032002.asp

Server-Side Asynchronous Web Methods
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnservice/html/service10012002.asp
(reference:.NET Delegates: Making Asynchronous Method Calls in the .NET Environment
http://msdn.microsoft.com/library/default.asp?url=/msdnmag/issues/01/08/Async/toc.asp)
---
Exploying XML in .NET Framework
http://msdn.microsoft.com/library/en-us/cpguide/html/cpconemployingxmlinnetframework.asp

XML Document Object Model (DOM)
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpguide/html/cpconxmldocumentobjectmodeldom.asp

Reading XML with the XmlReader
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpguide/html/cpconreadingxmlwithxmlreader.asp

XML and the DataSet
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpguide/html/cpconXMLDataSet.asp

DataSets, Web Services, DiffGrams, Arrays, and Interoperability
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnservice/html/service02112003.asp

XPathNavigator in the .NET Framework
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpguide/html/cpconxpathnavigatorinnetframework.asp
(
a XPath Tutorial
http://www.zvon.org/xxl/XPathTutorial

XML Path Language (XPath) 2.0
http://www.w3.org/TR/xpath20/

XML in a Nutshell Chapter 9: XPath
http://www.zvon.org/xxl/XPathTutorial/General/examples.html

XML Namespaces and How They Affect XPath and XSLT
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnexxml/html/xml05202002.asp
)

XML Schema Object Model (SOM)
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpguide/html/cpconxsdschemaobjectmodelsom.asp

XML Schemas (XSD)
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/xmlsdk/html/xmconXMLSchemas.asp

Validation of XML with Schemas
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpguide/html/cpconvalidationofxmlwithschemas.asp

SQLXML 2.0 RTM download
http://www.microsoft.com/downloads/details.aspx?displaylang=en&FamilyID=C0C94EEF-06AB-40A2-883C-8F5DB2E218F2

-----

UDDI: an XML Web Service
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnexxml/html/xml12182000.asp

Publishing and Discovering Web Services with DISCO and UDDI
http://msdn.microsoft.com/msdnmag/issues/02/02/xml/default.aspx

Web Service Description and Discovery Using UDDI, Part I
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnservice/html/service10032001.asp

Web Service Description and Discovery Using UDDI, Part II
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnservice/html/service10172001.asp

----

Versioning Options( for Web Service)
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnservice/html/service10152002.asp

Web Services Security (WS-Security)
http://msdn.microsoft.com/webservices/understanding/webservicebasics/default.aspx?pull=/library/en-us/dnglobspec/html/ws-security.asp

posted @ 2004-07-17 23:17 懒惰的车轮 阅读(630) | 评论 (0)编辑
现在有很多人在专注于,Visual Studio 2005 Team System,我们也来看看,这是微软的官方网站:Visual Studio 2005 Team System
posted @ 2004-05-28 15:20 懒惰的车轮 阅读(760) | 评论 (0)编辑
posted @ 2004-05-28 15:18 懒惰的车轮 阅读(620) | 评论 (0)编辑

 

posted @ 2004-05-28 15:17 懒惰的车轮 阅读(921) | 评论 (2)编辑