我对这个有点难过。有人有主意吗?我将尝试尽可能简短地列出这个例子。
针对SQL 2005数据库创建Silverlight 3.0应用程序。使用RIA服务和实体框架进行数据访问。
我需要能够针对表格填充网格。但是,我的网格UI和我的表结构是不同的。基本上我的网格需要将行转换为列(如PIVOT表)。以下是我的挑战/假设
那么,我如何创建一个具有动态属性的对象,以便我可以绑定到网格。我所拥有的每个想法(多维数组,哈希表等)分崩离析b / c SL需要绑定属性,我无法手动添加/填充数据行,我无法弄清楚一种添加动态属性的方法。我看过一篇关于涉及链表的解决方案的文章,但我正在寻找一个更好的选择。它可能归结为制作一个特殊的“Cody Grid”,它将成为一堆文本框/标签。可行,但我会失去一些用户期望的网格功能
我能够提出的唯一解决方案是在SQL 2005中创建PIVOT表查询并使用基于该查询/视图的实体。 SQL 2008会帮助我。我宁愿在Silverlight中这样做,但如果这是最后的手段,那就这样吧。如果我去PIVOT路线,我如何在Entity Framework中实现不断变化的数据结构?
数据样本。
名称日期值
Cody 1/1/09 15
Cody 1/2/09 18
Mike 1/1/09 20
Mike 1/8/09 77
网格UI应该看起来像
Name 1/1/09 1/2/09 1/3/09 .... 1/8/09
Cody 15 18 NULL NULL
Mike 20 NULL NULL 77
Cody
答案 0 :(得分:1)
我的团队提出了一个很好的解决方案。我不确定谁值得信用,但它在谷歌的某个地方。到目前为止它的效果非常好。
本质上,解决方案归结为使用反射基于此动态数据构建动态对象。该函数采用二维数组并将其转换为List 具有可绑定属性的对象。我们将此流程放在WCF服务中,它似乎完全符合我们目前的需求。
以下是使用Reflection
构建对象的一些代码AppDomain myDomain = AppDomain.CurrentDomain;
AssemblyName myAsmName = new AssemblyName("MyAssembly");
AssemblyBuilder myAssembly = myDomain.DefineDynamicAssembly(myAsmName, AssemblyBuilderAccess.Run);
ModuleBuilder myModule = myAssembly.DefineDynamicModule(myAsmName.Name);
TypeBuilder myType = myModule.DefineType("DataSource", TypeAttributes.Public);
string columnName = "whatever";
for (int j = 0; j <= array.GetUpperBound(1); j++)
{
Type properyType = typeof(T);
FieldBuilder exField = myType.DefineField("_" + "columnName" + counter, properyType, FieldAttributes.Private);
//The following line is where I’m passing columnName + counter and getting errors with some strings but not others.
PropertyBuilder exProperty = myType.DefineProperty(columnName + counter.ToString(), PropertyAttributes.None, properyType, Type.EmptyTypes);
//Get
MethodBuilder exGetMethod = myType.DefineMethod("get_" + "columnName" + counter, MethodAttributes.Public, properyType, Type.EmptyTypes); ILGenerator getIlgen = exGetMethod.GetILGenerator();
//IL for a simple getter:
//ldarg.0
//ldfld int32 SilverlightClassLibrary1.Class1::_Age
//ret
getIlgen.Emit(OpCodes.Ldarg_0);
getIlgen.Emit(OpCodes.Ldfld, exField);
getIlgen.Emit(OpCodes.Ret);
exProperty.SetGetMethod(exGetMethod);
//Set
MethodBuilder exSetMethod = myType.DefineMethod("set_" + "columnName" + counter, MethodAttributes.Public, null, new Type[] { properyType }); ILGenerator setIlgen = exSetMethod.GetILGenerator();
//IL for a simple setter:
//ldarg.0
//ldarg.1
//stfld int32 SilverlightClassLibrary1.Class1::_Age
//ret
setIlgen.Emit(OpCodes.Ldarg_0);
setIlgen.Emit(OpCodes.Ldarg_1);
setIlgen.Emit(OpCodes.Stfld, exField); setIlgen.Emit(OpCodes.Ret);
exProperty.SetSetMethod(exSetMethod);
counter++;
}
finished = myType.CreateType();
答案 1 :(得分:0)
您可以使用关联的绑定动态设置列(确保AutoGenerateColumns已关闭):
例如,名称列:
DataGridTextColumn txtColumn = new DataGridTextColumn();
textColumn.Header = "Name";
textColumn.Binding = new Binding("FirstName");
myDataGrid.Columns.Add(txttColumn);
用于存储查询数据的ObservableCollection可能会被覆盖以支持透视,确保更改DataGrid列的绑定,如上所示。
注意:这是相当数量的挥手我敢肯定(一年多没碰过银光);但我希望这足以制定另一种策略。
答案 2 :(得分:0)
如果您正在使用二维数组,那么如上所示动态添加列将不起作用。 问题在于silverlight无法理解列与列表的绑定。
所以我们必须创建带有行转换器的行列表,它们将代表我们的二维数组。
这个为我工作