3

私は.NETが得意ではありませんが、学んでいます(少なくともしようとしています!;))。しかし、私が取り組んでいるこのコードのビットは私を困惑させました。私がやりたいのは、と呼ばれるSQL Server 2008データベーステーブルにComment行を挿入し、この挿入された行のIDを使用して、2番目のテーブル(CommentOtherAuthor)に新しいデータ行を入力することです。基本的に、コメントには複数の作成者を含めることができます。

コードは次のとおりです。

public static Comment MakeNew(int parentNodeId, string firstname, string surname, string occupation, string affiliation, string title, string email, bool publishemail, bool competinginterests, string competingintereststext, string[] otherfirstname, string[] othersurname, string[] otheroccupation, string[] otheraffiliation, string[] otheremail, bool approved, bool spam, DateTime created, string commentText, int statusId)
{
        var c = new Comment
            {
                ParentNodeId = parentNodeId,
                FirstName = firstname,
                Surname = surname,
                Occupation = occupation,
                Affiliation = affiliation,
                Title = title,
                Email = email,
                PublishEmail = publishemail,
                CompetingInterests = competinginterests,
                CompetingInterestsText = competingintereststext,
                OtherFirstName = otherfirstname,
                OtherSurname = othersurname,
                OtherOccupation = otheroccupation,
                OtherAffiliation = otheraffiliation,
                OtherEmail = otheremail,
                Approved = approved,
                Spam = spam,
                Created = created,
                CommenText = commentText,
                StatusId = statusId
            };

        var sqlHelper = DataLayerHelper.CreateSqlHelper(umbraco.GlobalSettings.DbDSN);

        c.Id = sqlHelper.ExecuteScalar<int>(
            @"insert into Comment(mainid,nodeid,firstname,surname,occupation,affiliation,title,email,publishemail,competinginterests,competingintereststext,comment,approved,spam,created,statusid) 
                values(@mainid,@nodeid,@firstname,@surname,@occupation,@affiliation,@title,@email,@publishemail,@competinginterests,@competingintereststext,@comment,@approved,@spam,@created,@statusid)",
            sqlHelper.CreateParameter("@mainid", -1),
            sqlHelper.CreateParameter("@nodeid", c.ParentNodeId),
            sqlHelper.CreateParameter("@firstname", c.FirstName),
            sqlHelper.CreateParameter("@surname", c.Surname),
            sqlHelper.CreateParameter("@occupation", c.Occupation),
            sqlHelper.CreateParameter("@affiliation", c.Affiliation),
            sqlHelper.CreateParameter("@title", c.Title),
            sqlHelper.CreateParameter("@email", c.Email),
            sqlHelper.CreateParameter("@publishemail", c.PublishEmail),
            sqlHelper.CreateParameter("@competinginterests", c.CompetingInterests),
            sqlHelper.CreateParameter("@competingintereststext", c.CompetingInterestsText),
            sqlHelper.CreateParameter("@comment", c.CommenText),
            sqlHelper.CreateParameter("@approved", c.Approved),
            sqlHelper.CreateParameter("@spam", c.Spam),
            sqlHelper.CreateParameter("@created", c.Created),
            sqlHelper.CreateParameter("@statusid", c.StatusId));

        c.OnCommentCreated(EventArgs.Empty);

        for (int x = 0; x < otherfirstname.Length; x++)
        {
            sqlHelper.ExecuteScalar<int>(
                @"insert into CommentOtherAuthor(firstname,surname,occupation,affiliation,email,commentid) values(@firstname,@surname,@occupation,@affiliation,@email,@commentid)",
                sqlHelper.CreateParameter("@firstname", otherfirstname[x]),
                sqlHelper.CreateParameter("@surname", othersurname[x]),
                sqlHelper.CreateParameter("@occupation", otheroccupation[x]),
                sqlHelper.CreateParameter("@affiliation", otheraffiliation[x]),
                sqlHelper.CreateParameter("@email", otheremail[x]),
                sqlHelper.CreateParameter("@commentid", 123)
            );
        }

        if (c.Spam)
        {
            c.OnCommentSpam(EventArgs.Empty);
        }

        if (c.Approved)
        {
            c.OnCommentApproved(EventArgs.Empty);
        }

        return c;
    }

キーラインは次のとおりです。

sqlHelper.CreateParameter("@commentid", 123)

現時点では、コメントのIDを123としてハードコーディングしていますが、実際には、コメントテーブルに挿入されたばかりのレコードのIDである必要があります。

新しいことをせずにテーブルコメントから最後の挿入を取得する方法が本当にわかりません

SELECT TOP 1 id FROM Comment ORDER BY id DESC

これを行うための最良の方法として私を襲うことはありません。

誰かがこれを機能させる方法を提案できますか?

どうもありがとう!

4

2 に答える 2

4

そのSELECT TOP 1 id ...クエリは、負荷がかかっているシステムでは、とにかく適切な結果を提供しない可能性があります。20または50のクライアントが同時にコメントを挿入している場合、テーブルを再度クエリするまでに、他の誰かのid...を取得する可能性が非常に高くなります。

これを行うための最良の方法は次のとおりです。

  • 元の挿入に句を追加しOUTPUT、新しく挿入されたものをキャプチャしますID
  • そのIDを2番目の挿入に使用します

次のようなもの:

c.Id = sqlHelper.ExecuteScalar<int>(
        @"insert into Comment(......) 
          output Inserted.ID                
          values(.............)",

このアプローチを使用すると、c.Id値は新しく挿入されたものになります。次の挿入ステートメントでそれをID使用してください。注:現在、おそらく常に1戻ってきています-ステートメントの影響を受ける行数...

このアプローチでは、テーブルに新しい行を挿入すると自動的に設定されるCommentタイプの列があることを前提としています。INT IDENTITY

for (int x = 0; x < otherfirstname.Length; x++)
{
        sqlHelper.ExecuteScalar<int>(
            @"insert into CommentOtherAuthor(.....) values(.....)",
            sqlHelper.CreateParameter("@firstname", otherfirstname[x]),
            sqlHelper.CreateParameter("@surname", othersurname[x]),
            sqlHelper.CreateParameter("@occupation", otheroccupation[x]),
            sqlHelper.CreateParameter("@affiliation", otheraffiliation[x]),
            sqlHelper.CreateParameter("@email", otheremail[x]),
            sqlHelper.CreateParameter("@commentid", c.Id)  <<=== use that value you got back!
        );
}
于 2012-06-02T21:24:00.447 に答える
0

Microsoft SQL Serverを使用していると仮定すると、列IdのプロパティIdentityがtrueに設定されるように、テーブルCommentを設計できます。このようにして、データベースは、行がテーブルに挿入されるたびにIDを生成して自動インクリメントします。

SQLリクエストでは次の行を使用する必要があります。

OUTPUT INSERTED.Id

リクエストの実行時にこのIDをC#コードに戻すため。

于 2012-06-02T21:39:47.630 に答える