0

質問: PetaPoco を使用して 4 つ以上のテーブルを結合し、タイプ A のオブジェクトにタイプ B の 5 つのメンバーを設定しようとしています (この質問と非常によく似ています: 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 タイプのインスタンスとして対応するプロパティにマップする必要があります。

4

2 に答える 2

0

なぜあなたはこれを行うことができません:

/////select をテストするための 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 の 2 つの列を追加します。同じ名前空間に新しいオブジェクトを作成するだけです。そのようです:

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

2 - ビュークラス InvestmentView を作成します (そのために Investment クラスを使用できます。名前を変更するだけです)

   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")
                    );
    }

このように、特別な処理が必要な唯一のクラスは、InvestmentView から POCO のフラット構造にデータを逆方向に処理する必要があるため、Investment クラスになります。

于 2013-03-06T16:12:16.707 に答える