PetaPoco中相同类型的多个连接

时间:2012-07-10 14:51:49

标签: c# orm petapoco

问题: 我正在尝试使用PetaPoco加入四个以上的表来填充A类型的对象,其中包含五个类型为B的成员(与此问题非常类似:https://stackoverflow.com/a/11275334/296296)。根据我的阅读,可以使用以下语法:

var result = db.Query<Investment>(new System.Type[] { typeof(Investment), typeof(Person), typeof(Person), typeof(Person), typeof(Person), typeof(Person) }, null, sql, null).FirstOrDefault();

sql的位置是:

        SELECT Investment.*, p1.*, p2.*, p3.*, p4.*, p5.* FROM Investment
        INNER JOIN People p1 ON Investment.OwnerID = p1.Id
        INNER JOIN People p2 ON Investment.ITOwnerID = p2.Id
        INNER JOIN People p3 ON Investment.InformationOwnerId = p3.Id
        INNER JOIN People p4 ON Investment.MaintenanceLeaderId = p4.Id
        INNER JOIN People p5 ON Investment.MaintenanceLeaderITId = p5.Id
        WHERE (Investment.Id = @0)

但它只是给我以下错误:

 Can't auto join Person as Investment has more than one property of type Person

任何有同样问题或有任何帮助的人?

背景:

我有以下(简化)数据库表:

Investment
--------------
Id
Name
OwnerId
ITOwnerId
InformationOwnerId
MaintenanceLeaderId
MaintenanceLeaderITId

People
--------------
Id
Name

我想将这些数据库表映射到的类是:

 Public class Investment {
    public int Id 
    public string Name
    public Person Owner
    public Person ITOwner
    public Person InformationOwner
    public Person MaintenanceLeader
    public Person MaintenanceLeaderIT
 }

 Public class Person {
    public int Id 
    public string Name
 }

为了做到这一点,我需要为Investment类中的每个Person类型加入People表,并将它们作为Person类型的实例映射到相应的属性。

2 个答案:

答案 0 :(得分:0)

你可以做到这一点的唯一方法是创建你自己的回调(而不是让它回退到当前被调用的自发现回调),你在那里连接投资对象上的每个Person对象。

查看http://www.toptensoftware.com/Articles/115/PetaPoco-Mapping-One-to-Many-and-Many-to-One-Relationships

答案 1 :(得分:0)

为什么你不能这样做:

/////用于测试选择的SQL代码

DECLARE @People TABLE (Id INT,  Name VARCHAR(50))
        INSERT INTO @People (Id,Name)
            SELECT 1,' John Smith' UNION ALL
            SELECT 2,'Albert Lee' UNION ALL
            SELECT 3,'Christina Wetherbe' UNION ALL
            SELECT 4,'Alice Cany' UNION ALL
            SELECT 5,'Jim Blabery' UNION ALL
            SELECT 6,'Octaviose Mayflower' UNION ALL
            SELECT 7,'Sandra Lee M' UNION ALL
            SELECT 8,'Some test user' UNION ALL
            SELECT 9,'Some test user 2' UNION ALL
            SELECT 10,'Some test user 3' UNION ALL
            SELECT 11,'Some test user 4' 


    DECLARE @Investment TABLE (
                    Id INT,
                    Name VARCHAR(50),
                    OwnerId INT,
                    ITOwnerId  INT,
                    InformationOwnerId INT,
                    MaintenanceLeaderId INT,
                    MaintenanceLeaderITId INT
                )


    INSERT INTO @Investment(Id,Name,OwnerId,ITOwnerId,InformationOwnerId,MaintenanceLeaderId,MaintenanceLeaderITId)
    SELECT 1,'INVESTMENT 1',1,2,1,3,4 UNION ALL
    SELECT 2,'INVESTMENT 2',1,3,2,3,2 UNION ALL
    SELECT 3,'INVESTMENT 3',3,1,3,3,4 UNION ALL
    SELECT 4,'INVESTMENT 4',5,4,4,2,3 UNION ALL
    SELECT 5,'INVESTMENT 5',6,5,5,7,6 UNION ALL
    SELECT 6,'INVESTMENT 6',8,6,6,7,8 UNION ALL
    SELECT 7,'INVESTMENT 7',9,8,7,4,5 UNION ALL
    SELECT 8,'INVESTMENT 8',11,8,8,6,11 UNION ALL
    SELECT 9,'INVESTMENT 9',10,9,9,10,9


    --SELECT * FROM @People
    --SELECT * FROM @Investment

     -- THIS IS YOUR SELECT STATEMENT to be uses in PetaPoco call
    SELECT unpv.Id,unpv.Name, unpv.INVTYPE,unpv.PersonId,p.Name FROM @Investment
    UNPIVOT(PersonId for INVTYPE in    (OwnerId,ITOwnerId,InformationOwnerId,MaintenanceLeaderId,MaintenanceLeaderITId))unpv 
    join @People p on unpv.PersonId = p.Id
    order by INVTYPE, PersonId

然后C#代码为

1 - 将您的投资POCO扩展为另外两列,INVTYPE和PersonId。只需在同一名称空间中创建新对象即可。像这样:

    public partial class Investment
    {
        [ResultColumn]
        public string INVTYPE { set; get; }
        [ResultColumn]
        public int PersonId { set; get; }
    }

2 - 创建viewclass InvestmentView(你可以使用你的投资类,只需重命名)

   var myInvestmentView = new InvestmentView
                            {
                              Id = result.Id,
                              Name = result.Name,
                              Owner = new Person{ Id = result.firstOrDefault(o => o.INVTYPE.Equals("OwnerId")).PersonId, Name =  result.firstOrDefault(o=> o.INVTYPE.Equals("OwnerId")).PersonName},
                              ITOwner  = new Person{ Id = result.firstOrDefault(o => o.INVTYPE.Equals("ITOwnerId")).PersonId, Name =  result.firstOrDefault(o=> o.INVTYPE.Equals("ITOwnerId")).PersonName},
                              InformationOwner  = new Person{ Id = result.firstOrDefault(o => o.INVTYPE.Equals("InformationOwnerId")).PersonId, Name =  result.firstOrDefault(o=> o.INVTYPE.Equals("InformationOwnerId")).PersonName},
                              MaintenanceLeader = new Person{ Id = result.firstOrDefault(o => o.INVTYPE.Equals("MaintenanceLeaderId")).PersonId, Name =  result.firstOrDefault(o=> o.INVTYPE.Equals("MaintenanceLeaderId")).PersonName},
                              MaintenanceLeaderIT = new Person{ Id = result.firstOrDefault(o => o.INVTYPE.Equals("MaintenanceLeaderITId")).PersonId, Name =  result.firstOrDefault(o=> o.INVTYPE.Equals("MaintenanceLeaderITId")).PersonName}
                            }  

3 - 使用返回列表中的数据填充该类

    using (var data = new Database(Config.MainDbConnectionName))
    {
       var result = data.Fetch<Investment,People>(
                        Sql.Builder
                           .Append("SELECT unpv.Id,unpv.Name, unpv.INVTYPE,unpv.PersonId,p.name as PersonName FROM Investment")
                           .Append(" UNPIVOT(PersonId for INVTYPE in    (OwnerId,ITOwnerId,InformationOwnerId,MaintenanceLeaderId,MaintenanceLeaderITId)) unpv")
                           .Append(" JOIN People p on unpv.PersonId = p.Id")
                           .Append(" WHERE (Investment.Id = @0)",InvId)
                           .Append(" ORDER BY INVTYPE, PersonId")
                    );
    }

这样,唯一需要特殊处理的类将是投资类,因为您需要将数据从投资视图向后处理为POCO的平面结构。