我的团队正在维护一个巨大的Client Server win32 Delphi应用程序.它是一个客户端/服务器应用程序(胖客户端),它使用DevArt(SDAC)组件连接到SQL Server.
业务逻辑经常"被困"在Component的事件处理程序中,无论如何,通过一定程度的重构,可以将业务逻辑移动到公共单元中(这项工作的很大一部分已经在重构期间完成了......维护遗留应用程序的人别写的非常令人沮丧,但这是一项非常普遍的工作).
现在有一个Web界面的请求,当然我有几个选项,在这个问题中我想关注VCL for web(intraweb)选项.
我们的想法是为客户端/服务器应用程序和Web应用程序使用公共代码(相同的pas文件).我听说很多人将遗留应用程序从delphi迁移到intraweb,但在这里我也试图保留Thick客户端.
这个想法是使用通用代码,可能会用一些编译器指令来编写特定的代码:
{$IFDEF CLIENTSERVER}
{here goes the thick client specific code}
{$ELSE}
{here goes the Intraweb specific code}
{$ENDIF}
Run Code Online (Sandbox Code Playgroud)
然后另一个问题是"迁移计划",假设我有300个功能,在第一个版本中,我将只在Web应用程序中提供50个.如何跟踪它?我在想(ab)使用Delphi接口来处理这个问题.例如,对于用户身份验证,我可以在过程中移动所有相关代码并声明如下界面:
type
IUserAuthentication= interface['{0D57624C-CDDE-458B-A36C-436AE465B477}']
procedure UserAuthentication;
end;
Run Code Online (Sandbox Code Playgroud)
通过这种方式,当我在两个应用程序(胖客户端和Intraweb)中实现IUserAuthentication接口时,我知道该功能已被"移植"到Web上.无论如何,我不知道这种方法是否有意义.我制作了一个原型来模拟整个过程.它适用于"Hello world"应用程序,但我想知道它是否对大型应用程序有意义,或者这种接口的想法只会适得其反并且会适得其反.
我的问题是:这种方法有意义吗?(接口的想法只是一个额外的想法,它不像上面描述的通用代码部分那么重要)它是一个可行的选择吗?
据我所知,这取决于很多类型的应用程序,无论如何我是CRM/Accounting域中的通用,并且单个安装上的并发用户数通常小于20,峰值为50.
额外评论(更新):我问这个问题是因为我没有n层应用程序,所以我认为Intraweb是拥有一个与胖客户端有共同代码的Web应用程序的唯一选择.在我的特定情况下,从Delphi代码开发Web服务是没有意义的,所以我可以选择使用ASP.NET编写Web界面(复制业务逻辑),但在这种情况下我无法利用公共代码.简单的方法.是的我可以使用dll,但我的代码不适合.
只是想知道是否有人对DevArt MySQL是否是MySQL连接器有任何看法?在过去,当我使用MySQL时--MySQL Connector真的很难用于C#ASP.NET开发工作.
任何人都可以提出一个意见,是否更好地使用DevArt或?
这是这个问题的后续事实:
从LINQpad迁移到适当的Visual Studio项目?
..但我无法让它正常工作.
回答这个问题的建议倾销的背景下装配出来的DLL,但尽管我已经做了,当我导入它作为一个参考,它不完全清楚,我,我怎么会产生这方面的实例,在数据库指向它实际上对它运行一个查询,如下所示:
var db = new ContextFromThatDLL(myconnectionstring);
var query = from a db.MYTABLE,其中a.ID == 1选择a;
额外的信息:
我在LinqPad中使用IQ驱动程序连接到Oracle.
我已经拥有DevArt的许可证(IQ驱动程序使用),但我知道IQ驱动程序从LINQ生成自己的SQL - 我更喜欢它.另外,我在LinqPad中开发查询,这对我的工作流程非常有用,但发现DevArt并不总能生成与IQ一样好的SQL.
我将 Entity Framework Core 2.1.4 与 Oracle 11 数据库和 Devart.Data.Oracle.EFCore 提供程序一起使用。数据库优先方法。
我想在插入时从 ID 列(主键)的序列值中获取,而无需每次都明确设置。因此,基于与 SQL Server 的类似信息,我按以下方式进行了操作:
实体
public class Foo
{
public int Id { get; set; }
public double Value { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
映射(OnModelCreating 方法)
modelBuilder.HasSequence<int>("SEQ_FOOS", schema: "SCHEMA")
.StartsAt(1)
.IncrementsBy(1);
modelBuilder.Entity<Foo>(entity =>
{
entity.ForOracleToTable("FOOS");
entity.HasKey(e => e.Id);
entity.Property(e => e.Id).ForOracleHasColumnName("ID").IsRequired().ForOracleHasDefaultValueSql("SELECT SEQ_FOO.NEXTVAL FROM DUAL");
entity.Property(e => e.Value).HasColumnName("VALUE");
});
Run Code Online (Sandbox Code Playgroud)
增值:
using (var dbContext = new FooDbContext())
{
var foo = new Foo()
{
Value = 5
};
dbContext.Foos.Add(foo); …Run Code Online (Sandbox Code Playgroud) 在 SQLite 中,数据库文件的大小是数据库的总体大小,但这不一定是实际使用空间的正确指示。如果删除数据,释放的空间不会返回给操作系统。必须执行 VACUUM 命令对数据库进行碎片整理并将未使用的空间释放回操作系统。
我正在使用SQLite 的Devart ADO.Net 数据提供程序。
有没有办法获取SQLite数据库的实际使用空间?
我使用devart(corelab)的Mydac组件从Delphi访问MySql(2006)我经常需要处理TClientDataSet中的数据什么是将TMyQuery的数据集转换为TClientDataSet的最佳方法目前我正在使用
var
MyQuery : TMyQuery;
Dsp : TDataSetProvider;
Cds : TClientDataSet;
begin
MyQuery := nil;
Dsp := nil;
Cds := nil;
try
MyQuery := TMyQuery.Create(nil);
Dsp := TDataSetProvider.Create(nil);
Cds := TClientDataSet.Create(nil);
MyQuery.Connection := TheConnection;
MyQuery.SQL.Text := CmdStr;
Dsp.DataSet := MyQuery;
Cds.SetProvider(Dsp);
Cds.Open;
////////////////////////////////////////////////////////////////////////
/// MAKE USES OF THE CDS //
////////////////////////////////////////////////////////////////////////
finally
FreeAndNil(Cds);
FreeAndNil(Dsp);
FreeAndNil(MyQuery);
end;
end;
Run Code Online (Sandbox Code Playgroud)
有没有更好的方法呢?
在我的应用程序中,我只使用DBAware组件(除了一些地方).
我有一个场景,我创建一个主数据集(例如客户),详细数据集(例如订单),子目录数据集(例如订单项).通常我允许用户进行更改(数据集处于浏览模式),然后我发布.简单.
无论如何编辑子数据集我想添加一种简单的撤消功能:一个打开一个表单来编辑数据集(即使用db componets,因此对表单的更改将改变数据集),如果用户取消操作我会喜欢在打开表单之前恢复数据集.
现在为了实现这一点,我可以考虑在一个TClientDataSet或类似的组件中制作数据集的副本,但还有其他技术吗?就像Delphi一样可以轻松地创建数据的"快照".使用伪代码:
MySubDetailDataSet.SaveSnapShot;
SubDetailForm.ShowModal;
if ModalResult = mrCancel then MySubDetailDataSet.RestoreSnapShot;
Run Code Online (Sandbox Code Playgroud)
这样的东西可能是"现成的"Delphi组件吗?
顺便说一句,我使用DevArt组件的SDAC,所以如果你知道一种技术只适用于那些组件而不是Delphi标准组件,那么欢迎!
我有一个未排序的数据集(来自Devart的TMSQuery),我无法使用ORDER BY排序,因为我在打开查询后操作记录,因此"ORDER BY"给出的顺序将丢失.
我不想重写整个逻辑,所以我应该找到一种方法来对数据集进行排序.
我可以将数据集分配给TMemDataSet(TMemDataSet是DevArt类)后代(来自Devart的TVirtualTable),但在此之后我如何排序(我需要按日期字段排序)?
我读过这个问题,但它没有完全包含我正在寻找的答案.
我们在Delphi 10中使用Unidac Stored Proc组件和Sybase 12.5驱动程序
在Sybase proc我们提出错误如下,我发现它正在重新启动但它没有显示错误消息.我没有在Unidac或任何其他问题?
if @number <> null
begin
select @errmsg = 'Already active for location '
raiserror 20001 @errmsg
return 1
end
Run Code Online (Sandbox Code Playgroud)
我在delphi中执行storedproc,如下所示
try
ExecProc;
except on E:Exception do
begin
ErrorMsg(EDatabaseError(ExceptObject).Message,0);
Exit;
end;
Run Code Online (Sandbox Code Playgroud)
但我们仍然无法捕获异常.
即使我尝试过如下.
try
UniStoredProc.StoredProcName := 'test';
UniStoredProc.ExecProc;
except
on E:EUniError do
ShowMessage(E.Message);
end
Run Code Online (Sandbox Code Playgroud)
相同的代码适用于Sybase 15客户端库
我们使用Sybase 15服务器和Sybase 12.5 Client库连接到服务器,这会有问题吗?之前我们使用BDE和Sybase 12.5客户端库,所以我们没有遇到任何问题,现在我们发现unidac存在这个问题
我在Oracle ADO.Net提供程序(DevArt的dotConnect Universal)中使用以下代码.有趣的是,它有时会起作用,然后大多数时候它会抛出Devart.Data.Oracle.OracleException: ORA-01722: invalid number
string sql = "SELECT DISTINCT B.PRICE_TIER_KEY,b.label, a.INSERT_DATE AS PriceEffectiveDate,B.PROGRAM_KEY AS PRICE_PROGRAM_KEY FROM GHX_MEMBER_TIER A INNER JOIN VHA_INT_PRICE_TIER B ON A.SRC_ID_VALUE = B.PRICE_TIER_KEY WHERE RowNum <=100";
DbProviderFactory dpf = DbProviderFactories.GetFactory(System.Configuration.ConfigurationManager.ConnectionStrings["Con_ORA_DevArt"].ProviderName);
DbConnection conn = dpf.CreateConnection();
conn.ConnectionString = System.Configuration.ConfigurationManager.ConnectionStrings["Con_ORA_DevArt"].ConnectionString;
DbCommand dbcmd = dpf.CreateCommand();
dbcmd.Connection = conn;
//dbcmd.Connection = uniConnection1;
dbcmd.CommandText = sql;
dbcmd.CommandType = CommandType.Text;
dbcmd.CommandTimeout = 0;
DataTable table = new DataTable();
try
{
System.Data.Common.DbDataAdapter da = dpf.CreateDataAdapter();
da.SelectCommand = dbcmd;
// Fill …Run Code Online (Sandbox Code Playgroud) devart ×10
delphi ×5
oracle ×2
2-tier ×1
ado.net ×1
core ×1
dataset ×1
delphi-2010 ×1
delphi-xe2 ×1
entity ×1
frameworks ×1
intraweb ×1
linqpad ×1
mydac ×1
mysql ×1
sql-server ×1
sqlite ×1
sybase ×1
unidac ×1