返回首页

简介
了一个网页,后端数据库的接线是很乏味。你必须使用某种类型的数据访问层(DAL),然后映射这个页面上的字段。这是重复和容易出错的代码。有众多的ORM工具,让您与数据库接口,但是,这并不帮助装载控制,提示和页面上的校验器,你。本文将探讨使用nHydrate作为一个DAL,提供了丰富的元数据,从而提供了一个释放一些单调乏味的手动了一个网页的接线。是什么nHydrate?
首先nHydrate短的解释,这是一个平台,让您的模型驱动的方式(或领域驱动设计DDD)软件开发。你设计了一个模型,包含实体和关系。还有发电机,阅读模式,并基于该模型的创建代码。当您需要更改您的应用程序设计,只需改变你的模型,并重新生成。一个数据库中安装控制数据库的更改和版本。你永远无法触摸的数据库。该数据库是不是模型。你有一个真正的模型。它确实减少错误大家都在执行重复性的任务时。
生成DAL的实体框架提供了元数据,可用于自动化,我们在网页上执行的许多任务。我们将看到如何创建提示和验证,以及在编译时检查的方式来控制数据绑定。使用编译器是一大利好。我总是试图把尽可能多的功能。如果添加在通过脚本或其他机制的标记代码,就会有问题,当你改变你的数据模型或进行其他活动。代号为王;编译器检查它!
此示例依赖于一个小的代码我身边的书面模型。一个nHydrate模型是用来创建一个DAL与数据库交互。生成的实体框架层周围有额外的扩展,属性和元数据,快速,方便编写应用程序。我的"; ORMMapquot;类执行通用功能的所有我需要做一个网页的工作。这个类是不是生成的框架的一部分,因为它是非常具体我的执行。你如何选择绑定或映射的用户界面是具体的,根据您的技术,如Web窗体,MVC的WinForms,等你需要写一个小的连接的代码,像我这样做。然而,各地的DAL的元数据,使得这并非易事。此范例的用途基于模型的元数据动态地插入页上的校验器所需的验证器 范围验证器正则表达式验证器验证在文本框的整数一样的数据类型基于元数据为文本框设置MAXSIZE从数据库中加载下拉列表加载分页电网处理数据分页多种UI控件绑定到实体框架对象验证保存并显示错误 消除视图状态
在此示例中,我可以绑定标签,文本框,复选框,单选按钮,列表和下拉菜单。我可以填充下拉列表,以及核对清单和电台列表。我的主要形式有非常少的代码,屏幕仍然加载/保存与验证功能。
我写连接代码只有少数方法。第一个允许你加载一个组合框。在页面初始化,我已经加入了列表加载代码。这额外的好处,我不需要视图状态。事实上,样本中的所有页面视图状态关闭。我们这里有约束力的方式并不需要的Viewstate在。让我们在一个添加/编辑页面寻找一个quot; Regionquo​​t;对象的第一个。我们的模型有3个实体:客户,国家和地区。一位顾客[0 .. 1]国家[0 .. 1]地区。这是一个非常简单的模型,用于演示如何绑定与协会的对象。
我的项目hasnbsp;两个基地的网页,从中我推导出所有的网页。首先是BasePage它什么也不做。它仅仅是一个基础。二是BasePersistablePage用于编辑网页,并已用于加载和保存的核心功能。它有三个主要方法:SetupBindings,的CreateObject,并保存数据。编辑页面重写这些方法来添加任何自定义代码需要绑定。下面是我的主要站点对象的类图。随着它们的基类型,您可以看到编辑和列表页。 "; ORMMapquot;对象展开,以显示它的方法。在这个类中,有没有代码与特定的对象(地区或客户列表)。这个类可用于从任何页面来处理任何生成的对象。{S0}
请记住,这些网页不会产生框架的组成部分。我们没有理由用我的语法或代码。我已经创建了"; ORMMapquot;类和基地的网页了加载和保存nHydrate对象的功能抽象。我提到这一点,因为它可能是一个奇怪的语法,我已经看到了足够的代码生成知道他们使用混淆我的怪异和繁琐的语法。 nHydrate是直实体框架。如果您有使用外汇,那么,是什么外国在我在代码中使用的对象。 我的页面
下面两个屏幕截图,区域对象名单。二是客户的编辑页面。我已经包括客户编辑屏幕,因为它是最复杂的,包含依赖对象。屏幕很简单,它仅仅是一个列表控件,允许数据输入。
{S2}
让我们开始与该地区的对象,因为它很简单。它有一个ID和Name属性。这是典型的查表。数据库是这些国家,地区,等他们只是一个主键和名称。当用户编辑这些对象之一,他是真正的编辑,主要是从来没有显示或编辑的名字。在该地区的编辑页面中,我重写"; SetupBindingsquot;方法。数据库上下文传递给我,所以我用它来查找实际的对象,我想绑定。我拉URL字符串的主键关闭。这个范例网站使用URL结构像quot;?/ regionedit.aspx ID = 2quot。这使得它便于用户书签的页面。在代码中,我也改变了头,以指示用户是否这是一个创建或编辑操作。
请注意代码的最后一行。这将绑定文本框名为quot; txtNamequot;区域对象。所有生成的实体有关联的枚举创建映射到各自的领域。这可以让你写的方法,可以通过枚举的具体领域的工作。这些都始终保持同步,因为它们产生的从你的nHydrate模型,就像对象本身。这行代码是映射的quot; Namequot; Region对象到TextBox领域。这行代码将双向绑定UI控件的EF对象。这里有没有神奇的字符串。我没有把现场指定quot; Namequot引号(如数据集)。我用Region对象提供的枚举。
只有一行代码地图,因为只有一个TextBox的文本框。您将需要为每个控件的代码行。有许多重载,每个过程控制类型之一。您可以添加更复杂的过载或其他。NET控件甚至第三方控制你买。只需添加一个新的控制类型的重载和添加任何逻辑需要处理的新的控制类型。
没有更比页面上的代码。有quot; CreateObjectquot;基页需要创建一个对象时调用的页面的方法,但是这仅仅是创建一个新的对象,并把它添加到默认上下文。如果你有更复杂的业务规则执行时加入这个对象的类型,你可以添加或从这里调用的逻辑。
我的整个珠江三角洲地区的编辑页面约50行代码。我认为,这是非常小的。请记住,在模型中定义的任何必要的验证,将自动被添加。
客户编辑页面是一个比较复杂的过程,但具有相同的结构。我们必须加载额外的控制,所以它是有意义在它的代码看起来太。在这段代码中,我们看到的"; InitializeListquot,使用的方法。这就是所谓的负载值列表,用户可以选择一个下拉。我们只是通过控制列表绑定和将要使用的文字和价值的领域。这些都是所有加载在OnInit事件,所以不存在ViewState中需要我的例子。后面的代码中,我们结合每个单独控制在一个特定的对象相应的属性。在此示例中,所有字段绑定到同一个对象,但是这是没有必要的。我们可以很容易地绑定UI控件关闭主或任何其他EF对象,我们希望的依赖对象。{C}
现在让我们看看在列表页。该地区列表页显示分页列表的区域,您可以从中选择,编辑或删除项目。显示列表的分页的大问题之一。没有必要担心这个了nHydrate删除你大部分的苦差事。下面的代码拉页偏移和记录每页面的URL字符串,并用它来拉一个从数据库中的数据列表。我用的是我写的UR​​L解析到我关心的细分PagingURL类。分页对象持有的页偏移和每页记录和信息传递到的数据查询方法。当这个调用返回,是一个名为quot传呼对象的其他财产; TotalRecordsquot;将包含一个相匹配的所有记录的计数的条件,从而使你在屏幕上建立寻呼机控制,当前页,总页数每页的记录,记录总数。
一旦返回的数据页,我只是把它绑定直接到网格。我建立了一个分页控制,我使用列表页,它只是需要返回的寻呼信息,并建立一个程式化的寻呼机。这是所有真正需要的是建立一个列表/编辑数据录入网站。

using (var context = new EFExampleEntities())

{

	var url = new PagingURL(this.Request.Url.AbsoluteUri);

	var paging = new Widgetsphere.EFCore.DataAccess.Paging

			(url.PageOffset, url.RecordsPerPage);

	grdItem.DataSource = context.Region.GetPagedResults(x => x.Name, paging);

	grdItem.DataBind();

	PagingControl1.Populate(paging);

}

现在让我们看看我们如何能够拉生成的对象的元数据。 "; ORMMapquot;类是没什么好说的,我们与实体框架对象的字段关联的控制清单。每个nHydrate实体框架对象都有一个关联的元数据的类,可以通过属性和拉用来拉在运行时模型信息。通用元数据将显示名称,正则表达式,并要求的。
显示名称是一个友好的名称,你定义一个字段。所以,例如"; FirstNamequot在数据库中可能quot;第一Namequot;或"PostalCodequot;可能";邮编codequot;这可以用来提示和验证控件。拉生成的对象的显示名称,你可以使用下面的代码。通过在实体的基础nHydrate EF对象。所有生成的对象是从这种类型的派生,所以这个例程将其中的任何工作。
private string GetDisplayName(Enum field)

{

	var context = new EFExampleEntities();

	var metadata = context.GetMetaData(context.GetEntityFromField(field));

	var a = metadata.GetType().GetField(field.ToString()).GetCustomAttributes

		(typeof(System.ComponentModel.DataAnnotations.DisplayAttribute), 

		true).FirstOrDefault();

	if (a == null) return field.ToString();

	else return ((System.ComponentModel.DataAnnotations.DisplayAttribute)a).Name;

}

如果没有显示在模型中定义的名称,数据库名称是使用。你可以做同样的事情,拉断的验证,正则表达式的要求(非空)属性。
private bool IsNullable(Enum field)

{

	var context = new EFExampleEntities();

	var metadata = context.GetMetaData(context.GetEntityFromField(field));

	var a = metadata.GetType().GetField(field.ToString()).GetCustomAttributes

		(typeof(System.ComponentModel.DataAnnotations.RequiredAttribute), 

		true).FirstOrDefault();

	return (a != null);

}

 

private string GetRegularExpression(Enum field)

{

	var context = new EFExampleEntities();

	var metadata = context.GetMetaData(context.GetEntityFromField(field));

	var a = metadata.GetType().GetField(field.ToString()).GetCustomAttributes

	(typeof(System.ComponentModel.DataAnnotations.RegularExpressionAttribute), 

	true).FirstOrDefault();

	if (a == null) return string.Empty;

	else return ((System.ComponentModel.DataAnnotations.RegularExpressionAttribute)a).

		Pattern;

}

注意的模式很简单,可通过对生成的所有对象的扩展方法检索的对象的元数据类。元数据类一样需要定义这些数据点属性,表达,最小 - 最大范围内,您可以使用该描述符类来构建复杂的UI结构与非特定的代码就可以跟踪对象的所有领域,所有作品任何模型实体。您可以抽象出你所有项目中使用一个共同的大会。
使用的另一个重要的和节省时间的功能点是发出了验证程序。一个常见的​​问题与UI的发展是要知道哪些领域应该对他们进行验证,并保持与数据库或项目经理变更业务规则作为DBA的变化。这是很容易忘记,在所有其他发展,特别是因为这些业务规则,而不是错误中的一些改变任意屏幕。现在,一个简单而优雅的解决方案就在眼前。只需使用元数据发出页面上的验证。如果现在有人nHydrate模式的变化和重新生成,验证程序模型驱动的,所以他们会重新配置自己没有进行任何代码更改。 动态校验
下面的程序返回一个验证器,您可以添加到窗体的Controls集合的列表。只需调用此方法来获取一个列表,动态地添加到您的网页。
public virtual IEnumerable<system.web.ui.control> GetValidators()

{

	var retval = new List<system.web.ui.control>();

	foreach (var control in _controlList.Keys)

	{

		var e = _controlList[control];

 

		//Determine if we need a required field validator

		if (NeedsValidatorRequired(e.Entity, e.Field, 

			e.CanHaveRequiredValidation, e.ForceRequiredValidation))

		{

			var r1 = new RequiredFieldValidator

			{

				ControlToValidate = control.UniqueID,

				Display = ValidatorDisplay.None,

				ErrorMessage = "The '" + GetDisplayName

					(e.Entity, e.Field) + "' is required!"

			};

			retval.Add(r1);

		}

 

		//Determine if we need a regular expression validator

		if (NeedsValidatorExpression(e.Entity, e.Field))

		{

			var r1 = new RegularExpressionValidator

			{

				ControlToValidate = control.UniqueID,

				Display = ValidatorDisplay.None,

				ErrorMessage = "The '" + GetDisplayName

				(e.Entity, e.Field) + "' is not the correct format!",

				ValidationExpression = GetRegularExpression

				(e.Entity, e.Field)

			};

			retval.Add(r1);

		} 

	}

	return retval;

}

注意,检查,以确定如果一个字段是必需的,若有发出所需的验证。然后确定如果Entity.Field验证表达式若有发出一个正则表达式验证。你可以使这个具体的需要您的情况。这些只是两个很容易的添加。同时请记住,这是所有的通用代码。这并不工作在任何一个国家或客户等特定对象。它适用于任何模型,你可以建立的所有对象。
这个简单的例子演示了如何用很少的代码可以创建相当强大的数据录入屏幕。整个想法是使用元数据来驱动您的应用程序。这是模型驱动开发要容易得多。如果你的模型支持额外的元数据属性,不只是一个ORM的映射可以处理相当复杂的情况下,很笼统。
这将让你开始与模型驱动开发的Web UI。这种技术可以让你保持你的标记小。我们没有手动添加验证器,我什至没有提到MaxLength属性的文本框设置。这可确保用户不能输入数据是太大外地。发出的信息可以在元数据定义可以在运行时代码和标记,从而减少了您编写的代码和相关的错误。历史2011年6月1日:战后初期|克里斯托弗ř DavisBen第四集

回答

评论会员:游客 时间:2012/01/27
我与其他战略努力实现的目标是一致的(宽松和透明的双向绑定)使用Spring框架,标准组件ASP.net和一些胶水代码块。他的工作是概念上的团结得非常好。可以分享经验
?Raghu Karupakala
评论会员:游客 时间:2012/01/27
这是一个了不起的的概念有一个UI和DB之间的粘合剂!如果实施得当,任何企业应用程序变成了蛋糕步行