1

我正在尝试在使用 iBATIS.NET 映射的类 O/R 中使用通用自定义集合接口(以支持使用 Microsoft Patterns and Practices Unity 进行注入)。有谁知道这是否可行,如果可以,该怎么做?

我有一个 IDataItemCollection<T> 接口,我映射到扩展 CollectionBase 的 SqlDataItemCollection<T>。我想在我的类中使用 IDataItemCollection<T>,以便可以将 SqlDataItemCollection<T> 与通过 Unity 扩展接口的其他类交换。iBATIS.NET 映射文件可以直接引用具体类,因为没有一个就没有另一个。

下面我包含了一个非常简化的代码、数据库和映射示例。我对 iBATIS.NET 完全陌生,现在真的只是想证明它的用途,所以请根据需要重新调整映射 XML。

非常感谢,

保罗


C# 代码

public interface IDataItem
{
    object Id { get; set; }
}

public class DataItem : IDataItem
{
    public object Id { get; set; }
}

public interface IDataItemCollection<T> : ICollection where T : IDataItem
{
    // Various Getters and Setters
...
}

public class SqlDataItemCollection<T> : CollectionBase, IDataItemCollection<T> where T : DataItem
{
    public SqlDataItemCollection() { }
    public SqlDataItemCollection(T injType) { }

    // Getters and Setters to implement interfaces
...
}

public class Foo : DataItem
{
    public Foo(IDataItemCollection<Bar> bars)
    {
        Bars = bars;
    }

    public IDataItemCollection<Bar> Bars { get; set; }
}

public class Bar : DataItem { }

SQL Server 2005 数据库

CREATE TABLE Foo
(
    Id bigint IDENTITY(1,1)
)

CREATE TABLE Bar
(
    Id bigint IDENTITY(1,1)
)

CREATE TABLE FooBar
(
    FooId bigint,
    BarId bigint
)

iBATIS.NET 映射.xml

<resultMaps>
    <resultMap id="FooResult" class="Foo">
        <result property="Id" column="Id"/>
        <result property="Bars" column="Id" select="SelectBarsInFoo" lazyLoad="false"/>
    </resultMap>

    <resultMap id="BarResult" class="Bar">
        <result property="Id" column="Id"/>
    </resultMap>
</resultMaps>

<statements>
    <select id="SelectFoo" resultMap="FooResult">
        SELECT Id
        FROM Foo
    </select>

    <select id="SelectBarsInFoo" parameterClass="long" resultMap="BarResult" listClass="SqlDataItemCollection`1[Bar]" >
        SELECT Bar.Id
        FROM Bar
        JOIN FooBar ON Bar.Id = FooBar.BarId
        WHERE FooBar.FooId = #value#
    </select>
</statements>
4

1 回答 1

0

在将我的应用程序的一部分重构回接口后,我也遇到了同样的问题。我通过显式实现我的集合的接口定义然后将实现复制为其具体类来解决它。这可能无法解决您的问题。

public interface IGroup { }
public class Group : IGroup { }
public class IGroupCollection : IList<IGroup> { }
public class GroupCollection : IGroupCollection { }

public interface IConcrete
{
    IGroupCollection Items { get; set; }
}

public class Concrete : IConcrete
{
    public GroupCollection Items { get; set; }
    IGroupCollection IConcrete.Items
    {
        get { return Items; }
        set { Items = value as GroupCollection; }
    }
}

这允许 iBATIS.NET 将项目添加到集合中而不会遇到类型转换错误,而显式接口实现允许我在IConcrete整个应用程序中使用 s 而无需参考实际Concrete或实际的GroupCollection.

于 2010-07-01T19:56:11.940 回答