【发布时间】:2014-02-20 16:48:13
【问题描述】:
场景:
我正在维护一个大型 ASP.NET 应用程序,其中所有方法都返回一个通用列表。这导致的主要问题是 ObjectDataSource 不支持返回通用列表的方法。
我想做的事:
想出一种在不重写现有方法的情况下使用 ObjectDataSource 的方法。我提供了一种可行的技术,但想知道是否有更好的方法。
我了解我正在尝试的任何方法都会对性能产生负面影响。我主要关心的是减少我必须花费在维护和增强此应用程序上的时间。但是,我想实施一种对性能影响最小的方法。
返回通用列表的方法示例
public static List<Widget> GetAll()
{
List<Widget> temp = new List<Widget>();
Widget w1 = new Widget();
w1.Name = "test 1";
Widget w2 = new Widget();
w2.Name = "test 2";
temp.Add(w1);
temp.Add(w2);
return temp;
}
以下方法可行,但我不确定这是最好的方法,因为它需要迭代列表项
public class Widgets : List<Widget>
{
public Widgets()
{}
}
public static Widgets GetAll2()
{
List<Widget> temp = WidgetManager.GetAll();
Widgets widgets = new Widgets();
foreach (Widget widget in temp)
{
widgets.Add(widget);
}
return widgets;
}
以下操作无效。
public class Widgets : List<Widget>
{
public Widgets()
{}
}
public static Widgets GetAll2()
{
List<Widget> tempWidgets1 = GetAll();
Widgets tempWidgets2 = (Widgets)tempWidgets1;
return tempWidgets2;
}
以下是基于KMP & kohrhner 提供的答案和评论的完整解决方案。上面的部分代码重复但更详细。
完成这项工作的关键是将以下构造函数添加到实体列表类。除了添加构造函数之外,不需要额外的代码来实现 IEnumerable。
public Widgets(IEnumerable collection) : base(collection) { }
数据访问层
请注意,数据访问层返回的 List 不适用于 ObjectDataSource。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using DemoClassLibrary.Entities;
namespace DemoClassLibrary.DAL
{
public class WidgetDAL
{
public static List<Widget> GetAll()
{
List<Widget> temp = new List<Widget>();
Widget w1 = new Widget();
w1.Name = "test 1";
Widget w2 = new Widget();
w2.Name = "test 2";
temp.Add(w1);
temp.Add(w2);
return temp;
}
}
}
实体
无需对实体类进行任何更改。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace DemoClassLibrary.Entities
{
public class Widget
{
public string Name
{
get;
set;
}
}
}
实体列表类
需要创建一个实体列表类才能使用 ObjectDataSource。我的一个关键要求是不能修改原始 DAL。然而,仍然需要使用 DAL 来填充实体列表类。完成这项工作的关键是添加以下构造函数。
public Widgets(IEnumerable collection) : base(collection) { }
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace DemoClassLibrary.Entities.Collections
{
public class Widgets : List<Widget>
{
public Widgets(IEnumerable<Widget> collection) : base(collection) { }
public Widgets()
{ }
}
}
业务逻辑层
使业务逻辑层工作的关键是实例化 Widgets 类。这有效地将List<Widget> 转换为Widgets。
小部件 tempWidgets2 = 新小部件(tempWidgets1)
using System.ComponentModel;
using DemoClassLibrary.DAL;
using DemoClassLibrary.Entities;
using DemoClassLibrary.Entities.Collections;
namespace DemoClassLibrary.BLL
{
[DataObjectAttribute()]
public class WidgetManager
{
public static Widgets GetAll()
{
List<Widget> tempWidgets1 = WidgetDAL.GetAll();
Widgets tempWidgets2 = new Widgets(tempWidgets1);
return tempWidgets2;
}
}
}
ASPX 页面
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="DemoWebApplication._Default" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False"
DataSourceID="ObjectDataSource1">
<Columns>
<asp:BoundField DataField="Name" HeaderText="Name" SortExpression="Name" />
</Columns>
</asp:GridView>
<asp:ObjectDataSource ID="ObjectDataSource1" runat="server"
OldValuesParameterFormatString="original_{0}" SelectMethod="GetAll"
TypeName="DemoClassLibrary.BLL.WidgetManager"></asp:ObjectDataSource>
</div>
</form>
</body>
</html>
【问题讨论】:
-
难道你不能让小部件拥有 List
(即将它传递给构造函数并将其存储为成员变量)吗?这样,您就可以从 Widgets 实现 IEnumerable 并推迟到拥有的列表或您想做的任何事情,以便它可以被 ObjectDataSource 使用。
标签: c# asp.net generics generic-list generic-collections