by WebSurfer
2010年8月6日 17:26
Web カスタムコントロールでは、Visual Studio でプロパティの初期値を設定する際、入力値をチェックして条件に合わなければ例外をスローするようにできます。以下の画像のような感じです。
具体的には、例えば以下のように、値の設定時に入力値をチェックして条件に合わなければ例外をスローするようにコーディングしたとします。
namespace CustomControlThrowExceptionTest
{
public class MyControl : WebControl
{
public decimal MaxValue
{
get
{
object obj = ViewState["MaxValue"];
return (obj != null) ? (decimal)obj : Decimal.MaxValue;
}
set
{
if (value < MinValue)
{
throw new Exception("MaxValueException");
}
ViewState["MaxValue"] = value;
}
}
public decimal MinValue
{
get
{
object obj = ViewState["MinValue"];
return (obj != null) ? (decimal)obj : Decimal.MinValue;
}
set
{
if (MaxValue < value)
{
throw new Exception("MinValueException");
}
ViewState["MinValue"] = value;
}
}
・・・中略・・・
}
}
上記のプロパティを含む Web カスタムコントロールを作って、それをページに配置します。
そして、Visual Studio のプロパティウィンドウで、例えば、まず MaxValue を 100 に設定し、次に MinValue に 200 を入力すると、上の画像のようなダイアログが現れて設定の誤りを知らせてくれます。
コンパイルして Bin フォルダに配置しても、App_Code フォルダにソースのままファイルを置いても同じ動作をします(条件をチェックして例外をスローします)。
Web ユーザーコントロールの場合は、チェックは実行時でないとできません(間違った初期値が設定できてしまいます)。
知ってました? こんなことは常識と言われるかもしれませんが、それを知った当時、Web ユーザーコントロールしか知らない未熟者だった自分には驚きでした。
by WebSurfer
2010年8月5日 12:31
DB のテーブルから一つの項目を選び、その項目の詳細を表示するというケースはよくあると思います。そのようなサンプルは Web から容易に見つかると思います。
では、一度に複数の項目を選んで、複数の項目の詳細を同時に表示するにはどうすればいいでしょうか?
SQL Server には IN 演算子というものがあって、それを利用するのがよさそうです。以下は SQL Server 2005 Online Book のサンプルです。
SELECT FirstName, LastName, e.Title
FROM HumanResources.Employee AS e
JOIN Person.Contact AS c
ON e.ContactID = c.ContactID
WHERE e.Title IN ('Design Engineer', 'Tool Designer', 'Marketing Assistant');
ASP.NET のアプリでは、CheckBoxList で複数の項目を選んで、Button クリックで GridView に選んだ項目の詳細を表示することを考えます。
ユーザーの選択結果によって動的にクエリ(上記で言うと、IN (...) の ... の部分)を変える必要があります。
他にもっとスマートなやり方があるかもしれませんが、プログラムで SELECT クエリを組み立てて処置するサンプルを書いておきます。
DB は Microsoft が無償提供している Northwind サンプルデータベースの Orders テーブルを使用しました。
<%@ Page Language="C#" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<script runat="server">
protected void Button1_Click(object sender, EventArgs e)
{
string selectedItems = "(";
int count = 0;
for (int i = 0; i < CheckBoxList1.Items.Count; i++)
{
if (CheckBoxList1.Items[i].Selected)
{
selectedItems += CheckBoxList1.Items[i].Value + ", ";
count++;
}
}
if (count > 0)
{
selectedItems =
selectedItems.TrimEnd(new char[] { ',', ' ' });
selectedItems += ")";
SqlDataSource2.SelectParameters.Clear();
SqlDataSource2.SelectCommand =
"SELECT * FROM [orders] WHERE [EmployeeID] IN "
+ selectedItems + " ORDER BY [EmployeeID]";
}
else
{
SqlDataSource2.SelectParameters.Clear();
}
}
</script>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>無題のページ</title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:SqlDataSource ID="SqlDataSource1"
runat="server"
ConnectionString="<%$ ConnectionStrings:Northwind %>"
SelectCommand="SELECT DISTINCT [EmployeeID] FROM [Orders] ORDER BY [EmployeeID]">
</asp:SqlDataSource>
<asp:CheckBoxList ID="CheckBoxList1"
runat="server"
DataSourceID="SqlDataSource1"
DataTextField="EmployeeID"
DataValueField="EmployeeID">
</asp:CheckBoxList>
<asp:Button ID="Button1"
runat="server"
Text="Show Selected Data"
onclick="Button1_Click" />
<asp:SqlDataSource ID="SqlDataSource2"
runat="server"
ConnectionString="<%$ ConnectionStrings:Northwind %>" >
</asp:SqlDataSource>
<asp:GridView ID="GridView1"
runat="server"
DataSourceID="SqlDataSource2">
</asp:GridView>
</div>
</form>
</body>
</html>
fb6e0f19-0c33-42fa-aac7-53c2c8e6f084|0|.0
Tags: SQL, IN
ASP.NET
by WebSurfer
2010年8月5日 12:28
VS2005 (Visual Studio 2005) で作る SqlDataSource の楽観的同時実行制御用クエリは、NULL に対応できないという問題があります。
すでに VS2010 がリリースされている 2010 年 8 月現在、2 世代前の VS2005 を使っている方はそれほど多くないと思いますが、念のため書いておきます。
VS2005 の SqlDataSource 作成ウィザードで、楽観的同時実行制御オプションを有効にしてクエリを自動生成した際、UPDATE, DELETE クエリが NULL に対応できていません。
例えば、memo というフィールドが NULL 許容の場合、以下のようになるべきところ、
WHERE (([memo] = @original_memo) OR ([memo] IS NULL AND @original_memo IS NULL)) ...
VS2005 では以下のようになってしまいます。
WHERE [memo] = @original_memo ...
SQL Server では、= や != などの比較演算子では、引数のいずれかまたは両方が NULL の場合、UNKNOWN が返されます。
従って、DB のフィールドに NULL があると、WHERE 句の条件が成立せず、クエリが実行されない(更新/削除に失敗する)という問題があります。
この問題に対応するには、手作業で、上記のように IS NULL を使って、クエリを書き直してやる必要があります。
VS2008 ではこのあたりは改善されています。VS2010 は未確認です(まさか元に戻っているようなことはないと思いますが)。
なお、型付 DataSet + TableAbapter を、Visual Studio のウィザードを利用して作る場合は、VS2005 でも上記のような問題はありません。