我们最近开始在我们的网站上使用动态数据模板,通过手动搭建某些"表",使用EnableDynamicData
扩展方法,并在某些GridViews/DetailsViews等上传递我们的模型类型。
这实际上工作得很好,并且已经在几个选定的页面上投入生产。此方法仅使用类型本身中的信息来创建包含所有元数据的MetaTable
,这些元数据可用于在一堆页面上生成动态字段和筛选器。
我注意到这种脚手架机制非常有限,因为它没有考虑与其他类型的关系(可以理解,因为根本没有上下文信息(。
现在问题来了:例如,是否可以从接口生成整个元模型?在我们的 Web 应用程序中,我们根本不直接访问DbContext
。我们在另一个模块中使用 OData 协议(通过 Wcf 数据服务(公开了我们的上下文,网站通过我们设计的新 DataSource 控件请求信息,该控件旨在通过 url 与 Wcf Data 进行通信。
由于我们对DynamicData非常陌生,我自己找不到一种方法来做到这一点。我尝试的第一件事是使用来自两种相关类型的信息创建我自己的MetaModel
实例,但我失败了,因为似乎没有办法手动生成它。最初,我想要的相当于这样的东西:
gridview.EnableDynamicData(typeof(Device));
gridview.EnableDynamicData(typeof(DeviceType));
在我们的模型中,Device
和 DeviceType
之间存在一对一的关系,我需要在页面的同一网格中显示两个模型的字段。我立即注意到第二个调用覆盖了第一个注册,因为弹出了错误。然后,我查看了反汇编的代码以了解它的实际工作原理,很明显我根本无法使用此方法。
在这一点上,我对整个MetaTable/MetaModel类进行了一些研究,以确定我是否可以自己创建表。通过使用 MetaTable.CreateTable 方法,我可以轻松地从类型中创建单个 MetaTable,但我仍然看不到如何自己创建关系。
最优雅的方法似乎是全力以赴地使用脚手架机制,并在 Global.asax 上注册整个上下文。然后我意识到我需要整个DbContext
类型(和实例(来生成元模型。
这里的整个问题是责任:我根本不想将DbContext
暴露给 Web 应用程序。它不会访问数据库。它所拥有的只是数据服务及其返回的模型(在共享程序集中(的 URL。同时,我需要具有关系的元数据来无缝生成 UI。
我有什么选择可以在这里保持分离?理想情况下,该网站将使用完整的脚手架系统,而不依赖于DbContext
实现和连接字符串等。我想创建一个接口来公开关系,有点像"假"数据上下文,但是我查看的所有注册方法,如MetaModel.RegisterContext,测试传递给它们的类型,检查它是DataContext
还是ObjectContext
,并尝试创建它的实例(这也使得抽象类的使用也是不可能的(。
通过使用这样的完整脚手架,我们还具有从查询字符串等自动获取默认值的优势,而无需在每个页面上编写这样的代码:
var table = MetaTable.CreateTable(typeof (Device));
var defaultValues = table.GetColumnValuesFromRoute(HttpContext.Current);
gridview.SetMetaTable(table, defaultValues);
也许甚至可以在服务器中创建MetaModel
并通过自定义 Wcf 服务公开它?然后,我将在 Web 应用程序启动中调用此服务,以一次性注册整个内容或类似的东西。
我们目前在 Web 层上使用 Asp.Net 4 (.Net 4.0( WebForms,并使用实体框架 5 Code First 进行模型映射。
目前您必须加载完整的元模型才能获得关系,我们没有解决方案。现在不确定这是否有帮助,但大卫·埃博做了一个示例,在这里看到了这个线程