首页 新闻 会员 周边

C# dynamic类型实体怎么绑定到GridView等控件

0
悬赏园豆:20 [已解决问题] 解决于 2014-11-25 16:08

dynamic中动态添加的属性,在绑定GridView等控件时找不到。难道数据容器控件不支持dynamic类型么?

List<EntityBase> list = new List<EntityBase>();
dynamic e1 = new EntityBase();
e1.Id = "001";
e1.Name = "qwe";
list.Add(e1);
dynamic e2 = new EntityBase();
e2.Id = "001";
e2.Name = "qwe";
list.Add(e2);
this.GridView1.DataSource = list;
this.GridView1.DataBind();

Id和Name是动态添加的两个属性,在绑定时提示找不到Id。有什么方式可以绑定动态类型么?

最终的阿瓦隆的主页 最终的阿瓦隆 | 初学一级 | 园豆:111
提问于:2014-11-25 11:31
< >
分享
最佳答案
0

已经找到解决方案了!大致说下吧:

关于C#4.0的特性dynamic类型(动态类型),这玩意可以说又是.NET的一大神器。但是用不好缺点也多多。我之所以要把动态类型用于到实体上(有人可能觉得我犯二,实体不应该是固定么),那也是有这样的需求:往往查询结果中的字段可能多余实体的属性,那么多出来的字段怎么存放,要么创建一个新的实体,要么就是用主从表关系放在关联的外键实体上,但有时表之间有没有明确建立关系,那么实体之间的关系也就不存在,无法存放在关联实体上。如果用动态类型,那么在运行时动态为实体增加一个临时属性存放值那是件多么美妙的事情。

可惜的是dynamic类型是4.0出的特性,表示GridView和DataGridView等控件无法绑定这个动态增加的属性。在调试状态看其DataSource属性时发现数据源中动态的属性值其实是存在也有值,但就是无法绑定到界面上。

这是我我来GridView绑定的方式:

<asp:BoundField DataField="Id" HeaderText="编号" />
<asp:BoundField DataField="Name" HeaderText="名称" />

既然值有,就是取不到,所以我改成了下面的方式:

<asp:TemplateField HeaderText="编号">
  <ItemTemplate>
    <%# ((dynamic)Container.DataItem).Id%>
  </ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="名称">
  <ItemTemplate>
    <%# ((dynamic)Container.DataItem).Name%>
  </ItemTemplate>
</asp:TemplateField>

这样写太麻烦了,为了调用方便为Container增加一个扩展方法进行类型转化就可以了。

到此问题基本解决,但是窗体的DataGridView怎么实现暂时没有研究。

最终的阿瓦隆 | 初学一级 |园豆:111 | 2014-11-25 13:54

通过动态执行代码来实现,有想法。不过还是麻烦了点。

幻天芒 | 园豆:37175 (高人七级) | 2014-11-25 14:37

@幻天芒: 其实我实体是用字典集合存放实体属性的,没打算用dynamic类型,所以就算查询结果多出属性实体仍旧可以以键值对方式存放,非实体本身属性取值绑定时用的键索引。但是只能通过<%# %>绑定,所以如果需要在DataKeys中绑定是非常不方便,因此才想到用dynamic类型。但是测试结果是dynamic也达不到要的效果。以上问题其实是解决了一个测试案例中遇到的问题,我原本的问题其实还没有解决。大神有什么好的思路吗?

最终的阿瓦隆 | 园豆:111 (初学一级) | 2014-11-25 14:51
其他回答(3)
0

http://www.cnblogs.com/jinzhao/archive/2009/06/07/1497961.html你可以参考一下

收获园豆:5
Mr.Brian | 园豆:1518 (小虾三级) | 2014-11-25 12:16
0

可以新建一个模型,针对你这个数据的模型。然后其他操作和你这个一样的。

收获园豆:5
大楚打码人 | 园豆:4313 (老鸟四级) | 2014-11-25 12:59
0

以前用控件的时候,一般是Repeater用的多点。一般来说GridView的数据源还是弄成强实体比较好。多出来的属性,作为这个强实体的扩展属性即可。这样能保证属性可控,能从避免在动态代码中,容易出现找不到属性的问题。就算是连表的结果,也可以扩展实体解决。

收获园豆:10
幻天芒 | 园豆:37175 (高人七级) | 2014-11-25 14:59

好的吧!关于实体继承,最早开始我也是这样用的,只是开发过程中,初创团队没约束好,产生了很多让人意想不到的情况,所以在后来的项目中从新搞了框架也把实体继承扩展屏蔽掉了,除非特殊情况才单独开实体或扩展原有实体,一般情况下是屏蔽实体扩展的。现在我们解决DataKeys这种需绑属性字段时仍然用的是扩展实体或者使用自定义隐藏列。至少这也是最高效最直接的解决方案,那些舍近取远的思路只是改进现状的一种尝试,寄希望于找到一种更合理的解决方案,可能到最后发现只是徒劳。

说个题外话:

扩展了实体需不需要单独的数据访问和业务逻辑,当时团队内部有争议,于是有人写有人不写。找个业务逻辑出现的位置就非常诡异。

我见过明明基类有这个属性,在扩展实体中竟然还写的,甚至编译器都警告了也不管的。

更有甚者,明明有一个Name的属性不用,偏要自己写一个XXXName。

你要说没规范,规范明明都贴在每个人电脑旁边了,所以有时思想是很难统一的。最后只能通过框架来强制限制了。

支持(0) 反对(0) 最终的阿瓦隆 | 园豆:111 (初学一级) | 2014-11-25 15:45

@最终的阿瓦隆:首先,cs代码的编译警告是一定要清零的,连这种都做不到的员工,是很不负责任的。其他的只能通过讨论,让大家达成共识,再犯,那就需要一定的惩罚了(比如给大家买零食)。我不知道贵团队的开发模式是怎样的,很多情况下,BLL是按照业务在分,没有根据Entity,也就不存在单独的数据访问和逻辑了。

支持(0) 反对(0) 幻天芒 | 园豆:37175 (高人七级) | 2014-11-25 16:02
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册