2009-01-15 50 views
2

我有一个几乎相同的数据库的两个版本。下面我创建了一个示例表来演示基本的区别,即ID列已经从整型身份更改为GUID并且各种属性已更新,在示例中,存档已被替换为readOnly和hidden:如何松散地耦合.NET应用程序中的数据库列?

Legacy版本:

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 
) 

我需要能够使用O/R映射工具,如NHibernate的连接到这些数据库版本中的一个或其他。我希望能够通过配置文件中的设置来告诉应用程序使用哪个版本。

我的最初的计划是创建用于业务逻辑的通用接口,并使用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; } 
} 

任何人都可以提出建议,如果这是可能的(特别是与团结和NHibernate),如果是如何创建的有关NHibernate的映射文件?

可替换地,任何人都可以提出任何解决方案来使用任何其他方法或其他IOC和O/R映射工具(商业或开源)的问题?

非常感谢,

保罗

回答

0

也许我没有正确理解你的问题,但像你需要实现类似的“工厂模式”听起来给我。

我最近使用工厂模式代码(C#)到两个数据层时,我工作的公司从JDE切换到SAP。我能够翻转一个配置开关在两个数据层之间切换,而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的推移,我不熟悉它...对不起。希望这可以帮助。

0

很难推荐不知道整个画面,但是......您可以通过使SP返回两个表结构的相同数据集来创建SP中的障碍物。

另一个abstruction我想到的,是你其实可以指定不同的hybernate映射文件,并用不同的文件,这取决于你连接到什么数据库的初始化休眠。

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的系统。