SQLDataSource虽然使用起来比较简单,但它与数据库之间的直接访问,导致我们在使用的过程中缺乏了灵活性。
在开发过程中我们为了实现程序的合理结构和良好的代码重用功能,一般会把程序用三层来进行架构。而SQLDataSource这种直接连接数据库的功能,对三层架构来说很难实现。
如果不用SQLDataSource控件,那GridView的好多功能就不能完全正常发挥其威力。为了解决这个问题,微软为我们提供了ObjectDataSource这个控件。
ObjectDataSource控件并不直接与数据库之间进行连接,可以通过对业务对象的调用,实现对数据库的操作。
一、ObjectDataSource控件的几个重要属性
SelectMethod:ObjectDataSource控件执行查询时调用的方法名。
DeleteMethod:ObjectDataSource控件执行删除时调用的方法名。
UpdateMethod:ObjectDataSource控件执行更新时调用的方法名。
InsertMethod:ObjectDataSource控件执行插入时调用的方法名。
二、ObjectDataSource控件的几个重要方法
Select():调用SelectMethod进行查询
Insert():调用InsertMethod进行插入
Update():调用UpdateMethod进行更新
Delete():调用DeleteMethod进行删除
三、ObjectDataSource控件的几个重要的子元素
InsertParameters:为InsertMethod的方法提供参数
UpdateParameters:为UpdateMethod的方法提供参数
DeleteParameters:为DeleteMethod的方法提供参数
SelectParameters:为SelectMethod的方法提供参数
四、举例
1.配置连接字符串
2.编写业务模块(此处我用数据库的insert/update/delete/select来替代,在实际应用中,业务模块远比此复杂)
在此业务功能模块用的是SQLDataSource对象读取数据的,当然也可以用ADO.NET来读取数据
public class FruitDA
{
private SqlDataSource sd;
public FruitDA()
{
sd = new SqlDataSource();
sd.ConnectionString = System.Configuration.ConfigurationManager.ConnectionStrings["conn1"].ToString();;
}
public DataView select()
{
sd.SelectCommand = "select * from fruit";
sd.DataSourceMode = SqlDataSourceMode.DataSet;
DataView ds = (DataView)sd.Select(DataSourceSelectArguments.Empty);
return ds;
}
public void update(string ids,string name,decimal price,string source,string stack)
{
sd.UpdateCommand = "update fruit set name = @name,price = @price,source = @source,stack = @stack where ids = @ids";
sd.UpdateParameters.Add("ids", TypeCode.String, ids);
sd.UpdateParameters.Add("name",TypeCode.String,name);
sd.UpdateParameters.Add("price", TypeCode.Decimal, price.ToString());
sd.UpdateParameters.Add("source",TypeCode.String,source);
sd.UpdateParameters.Add("stack",TypeCode.String,stack);
sd.Update();
}
public void insert(string ids, string name, decimal price, string source, string stack)
{
sd.InsertCommand = "insert into fruit (ids,name,price,source,stack) values(@ids,@name,@price,@source,@stack)";
sd.InsertParameters.Add("ids", TypeCode.String, ids);
sd.InsertParameters.Add("name", TypeCode.String, name);
sd.InsertParameters.Add("price", TypeCode.Decimal, price.ToString());
sd.InsertParameters.Add("source", TypeCode.String, source);
sd.InsertParameters.Add("stack", TypeCode.String, stack);
sd.Insert();
}
public void delete(string ids)
{
sd.DeleteCommand = "delete from fruit where ids = @ids";
sd.DeleteParameters.Add("ids",TypeCode.String,ids);
sd.Delete();
}
}
3.配置ObjectDataSource和GridView,实现update/select/delete功能
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" DataKeyNames="ids" DataSourceID="s">
<Columns>
<asp:CommandField ShowDeleteButton="True" ShowEditButton="True" />
<asp:BoundField DataField="ids" />
<asp:BoundField DataField="name" />
<asp:BoundField DataField="price" />
<asp:BoundField DataField="source" />
<asp:BoundField DataField="stack" />
</Columns>
</asp:GridView>
<asp:ObjectDataSource ID="s" runat="server" SelectMethod="select" TypeName="FruitDA" DeleteMethod="delete" UpdateMethod="update" InsertMethod="insert" >
<DeleteParameters>
<asp:Parameter Name="ids" Type="String" />
</DeleteParameters>
<UpdateParameters>
<asp:Parameter Name="ids" Type="String" />
<asp:Parameter Name="name" Type="String" />
<asp:Parameter Name="price" Type="Decimal" />
<asp:Parameter Name="source" Type="String" />
<asp:Parameter Name="stack" Type="String" />
</UpdateParameters>
<InsertParameters>
<asp:ControlParameter Name="ids" ControlID = "txtIds" Type="String" />
<asp:ControlParameter Name="name" ControlID = "txtName" Type="String" />
<asp:ControlParameter Name="price" ControlID = "txtPrice" Type="Decimal" />
<asp:ControlParameter Name="source" ControlID = "txtSource" Type="String" />
<asp:ControlParameter Name="stack" ControlID = "txtStack" Type="String" />
</InsertParameters>
</asp:ObjectDataSource>
<asp:TextBox ID="txtIds" runat="server"></asp:TextBox>
<asp:TextBox ID="txtName" runat="server"></asp:TextBox>
<asp:TextBox ID="txtPrice" runat="server"></asp:TextBox>
<asp:TextBox ID="txtSource" runat="server"></asp:TextBox>
<asp:TextBox ID="txtStack" runat="server"></asp:TextBox><br />
<asp:Button ID="Button1" runat="server" Text="Insert" OnClick="Button1_Click" />
4.实现插入功能的代码
protected void Button1_Click(object sender, EventArgs e)
{
s.Insert();
}
(车延禄)
自定义Parameter
在SqlDataSource和ObjectDataSource控件中有七种类型的参数,但这七种类型的参数有时还不能满足我的需求。
问题提出:
在ObjectDataSource中,是通过SelectMethod、InsertMethod、UpdateMethod和DeleteMethod四个属性来调用业务逻辑对象的方法,业务逻辑对象的方法需要的参数可以通过ObjectDataSource控件相应的Parameter属性传入。这些Parameter的参数来源与参数类型是固定的,在遇到以下两种情况是无法解决的。
a、参数不是直接来源于控件、Session、Cookie、QueryString等,而是把某个对象中的属性值作为参数传后业务逻辑的方法,如何进行参数赋值。
b、业务逻辑方法的形参不是常用的string、int、float等类型,而是一个自定义的类型,如何进行参数赋值。
自定义Parameter:
要自定义Parameter需要编写一个类派生自Parameter类,并且重写其Evaluate方法。
public class CustomParameter:Parameter
{
object obj; //传递给业务逻辑对象的形参的值
public object Value
{
get{ return obj;}
set{ obj = value;}
}
public CustomParameter(){}
//传递参数名和参数值,调用父类构造方法给参数名赋值,并把参数值保存到obj里。
public CustomParameter(string name, object value) : base(name)
{
obj = value;
}
public CustomParameter(string name, TypeCode type, object value) : base(name, type)
{
obj = value;
}
public CustomParameter(CustomParameter original) : base(original)
{
obj = original.Value;
}
//被DataSource控件绑定时自动调用,更新并返回 Parameter 对象的值。
protected override object Evaluate(HttpContext context, Control control)
{
return Value;
}
}
数据访问逻辑:
public class FruitDB
{
private SqlConnection conn;
public FruitDB()
{
conn = new Conn().Connection;
}
public List<FruitData> select()
{
List<FruitData> fruitlist = new List<FruitData>();
SqlCommand cmd = conn.CreateCommand();
cmd.CommandText = "select * from fruit";
conn.Open();
SqlDataReader dr = cmd.ExecuteReader();
while (dr.Read())
{
FruitData data = new FruitData(dr["ids"].ToString(),dr["name"].ToString(),decimal.Parse(dr["price"].ToString()),dr["source"].ToString(),dr["stack"].ToString(),dr["image"].ToString());
fruitlist.Add(data);
}
conn.Close();
return fruitlist;
}
public void insert(FruitData fd)
{
SqlCommand cmd = conn.CreateCommand();
cmd.CommandText = "insert into fruit values(@ids,@name,@price,@source,@stack,@image)";
cmd.Parameters.AddWithValue("@ids",fd.Ids);
cmd.Parameters.AddWithValue("@name",fd.Name);
cmd.Parameters.AddWithValue("@price", fd.Price);
cmd.Parameters.AddWithValue("@source",fd.Source);
cmd.Parameters.AddWithValue("@stack",fd.Stack);
cmd.Parameters.AddWithValue("@image",fd.Image);
conn.Open();
cmd.ExecuteNonQuery();
conn.Close();
}
}
FruitData实体类:
public class FruitData
{
private string ids,name,price,source,stack,image;
public string Ids
{
get{ return ids;}
set{ ids = value;}
}
public string Name
{
get{ return name;}
set{ name = value;}
}
public decimal Price
{
get{ return price;}
set{ price = value;}
}
public string Source
{
get{ return source;}
set{ source = value;}
}
public string Stack
{
get{ return stack;}
set{ stack = value;}
}
public string Image
{
get{ return image;}
set{ image = value;}
}
public FruitData(string ids, string name, decimal price, string source, string stack, string image)
{
this.ids = ids;
this.name = name;
this.price = price;
this.source = source;
this.stack = stack;
this.image = image;
}
}(车延禄)
界面代码:
<asp:GridView ID="GridView1" runat="server" DataSourceID="ObjectDataSource1">
</asp:GridView>
<asp:ObjectDataSource ID="ObjectDataSource1" runat="server" InsertMethod="insertdb"
SelectMethod="select" TypeName="FruitDB">
</asp:ObjectDataSource>
<asp:TextBox ID="txtIds" runat="server"></asp:TextBox>
<asp:TextBox ID="txtName" runat="server"></asp:TextBox>
<asp:TextBox ID="txtPrice" runat="server"></asp:TextBox>
<asp:TextBox ID="txtSource" runat="server"></asp:TextBox>
<asp:TextBox ID="txtStack" runat="server"></asp:TextBox>
<asp:TextBox ID="txtImage" runat="server"></asp:TextBox><br />
<asp:Button ID="Button1" runat="server" Text="Button" OnClick="Button1_Click" />
这里需要注意的是:在insert的时候不要加入 DataObjectTypeName="FruitData",否则会报“没有可以插入的值。请检查“values”” 的错误,而在更新删除的时候,必须要加入DataObjectTypeName="FruitData"这句声明。
后置代码类:
//构造一个FruitData对象
FruitData fd = new FruitData(txtIds.Text, txtName.Text, decimal.Parse(txtPrice.Text), txtSource.Text, txtStack.Text, txtImage.Text);
ObjectDataSource1.InsertParameters.Clear();
//创建自定义的的Parameter,并创建的FruitData对象传入
CustomParameter cp = new CustomParameter("fd", fd);
//添加自定义的参数
ObjectDataSource1.InsertParameters.Add(cp);
//执行查询
ObjectDataSource1.Insert();