我有几个完全相同的数据库的两个版本。下面我创建了一个Example表来演示基本的差异,即ID列已从Integer Identity更改为GUID并且各种属性已更新,在示例archived中已替换为readOnly并隐藏:
传统版本:
CREATE TABLE Example
(
--Data Identity (maps to DbId in the example code)
Id int IDENTITY PRIMARY KEY,
--Example columns
SomeValue varchar(50),
AnotherValue int,
--Data Properties
Archived bit
)
新版本:
CREATE TABLE Example
(
--Data Identity (maps to DbId in the example code)
Id uniqueidentifier PRIMARY KEY,
--Example columns
SomeValue varchar(50),
AnotherValue int,
--Data Properties
ReadOnly bit,
Hidden bit
)
我需要能够使用诸如NHibernate之类的O / R映射器来连接这些数据库版本中的一个或另一个。我希望能够通过配置文件中的设置告诉应用程序使用哪个版本。
我最初的计划是为业务逻辑创建一个通用接口,并使用Unity等IoC容器在配置文件中的相关具体类之间进行交换。
下面是我为测试这个理论而创建的代码示例:
public interface IDataIdentity
{
object Id { get; }
}
public class LegacyDataIdentity : IDataIdentity
{
public virtual long DbId { get; set; }
public object Id
{
get { return DbId; }
}
}
public class NewDataIdentity : IDataIdentity
{
public virtual Guid DbId { get; set; }
public object Id
{
get { return DbId; }
}
}
public interface IDataProperties
{
bool ReadOnly { get; set; }
bool Hidden { get; set; }
}
public class LegacyDataProperties : IDataProperties
{
public virtual bool Archived { get; set; }
public bool ReadOnly
{
get { return Archived; }
set { Archived = value; }
}
public bool Hidden
{
get { return Archived; }
set { Archived = value; }
}
}
public class NewDataProperties : IDataProperties
{
public virtual bool ReadOnly { get; set; }
public virtual bool Hidden { get; set; }
}
public class DataItem
{
public DataItem(IDataIdentity dataIdentity, IDataProperties dataProperties)
{
DataIdentity = dataIdentity;
DataProperties = dataProperties;
}
public IDataIdentity DataIdentity { get; set; }
public IDataProperties DataProperties { get; set; }
}
public class Example : DataItem
{
public Example(IDataIdentity dataIdentity, IDataProperties dataProperties)
: base(dataIdentity, dataProperties)
{
}
public virtual string SomeValue { get; set; }
public virtual int AnotherValue { get; set; }
}
任何人都可以建议这是否可行(特别是Unity和NHibernate),如果可以的话,如何创建相关的NHibernate映射文件?
或者,任何人都可以使用任何其他方法或其他IoC和O / R映射工具(商业或开源)建议任何解决问题的方法吗?
非常感谢,
保
答案 0 :(得分:2)
为什么不抽象数据提供程序,实现2个版本(一个版本具有旧数据项的nhibernate映射,另一个版本适用于新数据项)。
稍微解释一下你的代码(为简洁起见,简化了):
public abstract class AbstractData
{
public abstract string SomeValue { get; set; }
public abstract bool ReadOnly { get; set; }
//etc.
}
public interface IDataProvider
{
AbstractData Get(object id);
}
public class LegacyData : AbstractData
{
// Implement AbstractData, and
public virtual long Id { get { return m_Id; } set { m_Id = value; };
private long m_Id;
}
public class LegacyDataNHibernateProvider : IDataProvider
{
public LegacyDataProvider()
{
// Set up fluent nhibernate mapping
}
public AbstractData Get(object id)
{
// Interpret id as legacy identifier, retrieve LegacyData item, and return
}
};
// Same again for new data provider
这样,你就不依赖于nhibernate(或数据库),你可以指定具有正确类型标识符的具体类(nhibernate可以处理)。这是我正在采用的方法,我目前必须针对现有数据库的SP进行映射,但稍后将迁移到新的基于ORM的系统。
答案 1 :(得分:0)
也许我没有正确理解你的问题,但听起来你需要实现类似“工厂模式”的东西。
当我工作的公司从JDE切换到SAP时,我最近使用工厂模式将代码(c#)编码为两个数据层。我能够翻转配置开关以在两个数据层之间切换,并且GUI不会知道任何不同。
以下是我发现的一些链接:
http://msdn.microsoft.com/en-us/library/ms954600.aspx http://www.allapplabs.com/java_design_patterns/factory_pattern.htm http://en.wikipedia.org/wiki/Abstract_factory_pattern
就NHibernate而言,我对它并不熟悉...抱歉。希望这会有所帮助。
答案 2 :(得分:0)
很难在不知道完整图片的情况下推荐,但是......你可以通过让SP为两个表结构返回相同的数据集来在SP中创建一个abstruction。
我想到的另一个缺点是,您实际上可以指定不同的hybernate映射文件,并根据您连接的数据库使用不同的文件初始化Hibernate。