迷失网络

如果你误读成“迷失公园”或“迷失侏罗纪”,那你可能真的迷失网络了。
随笔 - 88, 评论 - 1932, 引用 - 106

导航

关于

lostinet@lostinet.com这个油箱不能用了。因为空间没了,lostinet.com指向为127.0.0.1 。。。

标签

每月存档

最新留言

广告

 

最近客户找我做一个更新SqlServer的算法,我在需求还算明确的情况下把代码写完,发了过去。
结果客户很快就打电话给我,说他们不是用 System.Data.SqlClient 的。要求我把代码改成OleDb的。

为了使程序能让OleDb和SqlClient都能用,我把程序的接口改为 IDbXXX .

可是问题出现了,OleDb竟然不把参数送到SqlServer那边去!

例如这样的代码,

其中 MyBussinessLogic 是我的实现。通过IDbXXX的方法,把CommandText,参数等信息放进去后,就执行Command 。 如果外面传一个 SqlTransaction 进来,那么是没有问题的。

但是如果外面传 OleDbTransaction 进来,那么这个OleDb的提供者就只把CommandText传到SqlServer去,那么执行当然会出错了。

以前没有用 OleDb 时,以为 SqlClient 只是性能上更加优化而已, 直到今天才知道还有这个问题存在。。

打印 | 张贴于 2004-09-03 03:20:00 | Tag:DotNet

留言反馈

#re: 第一次用OleDB,结果被它玩死。。 编辑
“请使用:来代替@ ”
这种方式好像是针对Oracle数据库的吧?
2006-10-24 09:44:00 | [匿名用户:zenp]
#re: 第一次用OleDB,结果被它玩死。。 编辑
请使用:来代替@
2006-07-13 15:27:00 | [匿名用户:nickppa]
#re:第一次用OleDB,结果被它玩死。。 编辑
第一次用OleDB,结果被它玩死。。ooeess
2005-06-08 16:42:00 | [匿名用户:皮带张力计]
#re:第一次用OleDB,结果被它玩死。。 编辑
^_~,pretty good!csharpsseeoo
2005-05-13 17:28:00 | [匿名用户:拉力试验机]
#re:第一次用OleDB,结果被它玩死。。 编辑
^_~,pretty good!18showsseeoo
2005-04-26 13:42:00 | [匿名用户:放大镜]
#re:第一次用OleDB,结果被它玩死。。 编辑
^_^,Pretty Good!
2005-04-15 19:53:00 | [匿名用户:流变仪]
#re:第一次用OleDB,结果被它玩死。。 编辑
^_^,Pretty Good!
2005-04-10 19:45:00 | [匿名用户:测汞]
#re: 第一次用OleDB,结果被它玩死。。 编辑
参数的问题倒是早就知道了,这是在实现应用程序同时支持SqlClient与OleDB接口时应该考虑到的问题,使用CommandBuilder也是一种解决的方法。
2004-09-03 23:14:00 | [匿名用户:niuke]
#re: 第一次用OleDB,结果被它玩死。。 编辑
我也遇到过同样的问题。
为了支持SqlServer和Access数据库,本打算当使用SqlServer数据库时用SqlClient而Access用OleDb。但后来也是因为OleDb中必须使用?表示参数而妥协全部使用OleDb。
我当时还考虑过自己实现 IDBXXX 接口。把SqlXXX和OleDbXXX封装在实现类中,为每个SQL语句写两个Command,但工作量太大了,最后放弃
2004-09-03 16:44:00 | [匿名用户:bobit]
#re: 第一次用OleDB,结果被它玩死。。 编辑
自从用了ORM就很久没有用过System.Data namespace了
2004-09-03 11:56:00 | [匿名用户:leighsword]
#re: 第一次用OleDB,结果被它玩死。。 编辑
Thanks all .

谢谢Saucer。不过我这里无法用 '?' 了。主要是因为我不想去算参数的个数和顺序以适应具体的CommandText。

Initial Category我也没有发现。呵呵。
不过代码我是测试过的,还没有等到说找不到Orders,就抛出“必须定义@empid"的错误了。

至于命名BusinessLogic是因为,我做的东西算法比例几乎占全部。例子只是分析OleDb那边的问题。

使用IDbXXX的目的不是要跨数据库服务器,而是要同时支持OleDb和SqlClient。

不用存储过程的原因是,数据库根本不是我的。数据库中有什么东西我根本无法知道,更不要说去写存储过程了。

今天我发现OleDbCommandBuilder.DeriveParameters(cmd);返回的OleDbParameter的Name是不带"@"的。看来有新的解决方案。
2004-09-03 10:56:00 | [匿名用户:Lostinet]
#re: 第一次用OleDB,结果被它玩死。。 编辑
@sauser:

Yeah, I'd more than agree that the name issue is not relelant to this specific problem. But I think it's quite a critical issue to a real programmer. Right?

It would be better to name that class as simple as Foo or Bar, but not MyBusinessLogic. It indeed reflects a further problem which could drive others mad when reading and understanding your code.

Believe me or not, naming helps thinking in software design. As soon as you realize it as a DAC, you know what to do next, in order to solve problem right, e.g., the portability issue.

Sorry for my off-topic comments here, if it's far too irrelevant. ;)
2004-09-03 10:55:00 | [匿名用户:JGTM'2004 [MVP]]
#re: 第一次用OleDB,结果被它玩死。。 编辑
奇怪居然说找不到对象“Orders”
2004-09-03 09:48:00 | [匿名用户:empName]
#re: 第一次用OleDB,结果被它玩死。。 编辑
Why not use stored procedure which includes a transaction inside?
2004-09-03 09:35:00 | [匿名用户:Alexander]
#re: 第一次用OleDB,结果被它玩死。。 编辑
不知道除了sqlserver还有哪种数据库能认识@para的格式
2004-09-03 09:27:00 | [匿名用户:rIPPER]
#re: 第一次用OleDB,结果被它玩死。。 编辑
namespace ConsoleApplication1
{
using System;
using System.Data;
using System.Data.Common;
using System.Data.OleDb;

class Class1
{
[STAThread]
static void Main(string[] args)
{
string connstr="Provider=SQLOLEDB;Data Source=(local);Initial Category=Northwind;Integrated Security=SSPI;";
using(OleDbConnection conn=new OleDbConnection(connstr))
{
conn.Open();
using(OleDbTransaction trans=conn.BeginTransaction())
{
using(IDataReader reader=MyBussinessLogic(trans,1))
{
while(reader.Read())
{
Console.WriteLine(reader.GetValue(0));
}
}
}
}
}

static public IDataReader MyBussinessLogic(IDbTransaction trans,int empid)
{
if(trans==null)throw(new ArgumentNullException("trans"));

IDbCommand cmd=trans.Connection.CreateCommand();
cmd.Transaction=trans;

cmd.CommandText="select ShipName from Orders where EmployeeID=@empid";

IDbDataParameter pEmplolyeeId=cmd.CreateParameter();
pEmplolyeeId.ParameterName="@empid";
pEmplolyeeId.DbType=DbType.Int32;
pEmplolyeeId.Value=empid;
cmd.Parameters.Add(pEmplolyeeId);

return cmd.ExecuteReader();
}
}
}
2004-09-03 09:27:00 | [匿名用户:转出来,看清楚一点]
#re: 第一次用OleDB,结果被它玩死。。 编辑
  严重关注该问题的解决。在我的中间层中就都是使用 IDbXXXX 的接口调用方式进行处理的,如真的OleDb不能传递事务对象的话,那就麻烦大了~~~
2004-09-03 09:13:00 | [匿名用户:SW515]
#re: 第一次用OleDB,结果被它玩死。。 编辑
I think JGTM'2004 [MVP] is missing the point here, the name is irrelevant, :-)

By the way, it should be "Initial Catalog"
2004-09-03 08:10:00 | [匿名用户:saucer]
#re: 第一次用OleDB,结果被它玩死。。 编辑
And actually, your so-called "BusinessLogic" is "DataAccessLogic". See? There is no changes in concern of business logic here, but why should you modify code in it? I think there must be a big misunderstanding on software layering and architecting issues in your mind.

All you have to do is to define a data access interface upon which your actual business logic components use to access all underlying data, and implement specific data access component against this data access interface to provide all the detail to actually access the data store. After this, you simply use a helper data access component FACTORY to instantiate proper data access component to use for the business logic components.

Have fun! :)
2004-09-03 07:14:00 | [匿名用户:JGTM'2004 [MVP]]
#re: 第一次用OleDB,结果被它玩死。。 编辑
In OleDb, parameters are position based while in SqlClient, it is name based

funny, in OleDb, somehow on my machine, "Initial Category" doesn't work


string connstr="Provider=SQLOLEDB;Data Source=(local);database=Northwind;Integrated Security=SSPI;";

.....

static public IDataReader MyBussinessLogic(IDbTransaction trans,int empid)
{
if(trans==null)throw(new ArgumentNullException("trans"));

IDbCommand cmd=trans.Connection.CreateCommand();
cmd.Transaction=trans;

cmd.CommandText="select ShipName from Orders where EmployeeID=?";

IDbDataParameter pEmplolyeeId=cmd.CreateParameter();
pEmplolyeeId.ParameterName="@empid";
pEmplolyeeId.DbType=DbType.Int32;
pEmplolyeeId.Value=empid;
cmd.Parameters.Add(pEmplolyeeId);

return cmd.ExecuteReader();
}

of coures, there goes your portability.....
2004-09-03 05:56:00 | [匿名用户:saucer]
对不起,目前本随笔不允许发表新评论.

Powered by: Joycode.MVC引擎 0.5.1.0