是否有一个初始化语法ExpandoObject,我可以在LINQ to XML查询中使用它以简化目的?
注意:查询的结果旨在传递到当前程序集的范围之外,因此匿名类型是不可能的(请参阅此处的原因).
我正在尝试使用如下的简短语法来创建动态/ expando对象:
public IEnumerable<dynamic> ParseUserXml(string strXmlUser) {
var qClients =
from client in xdoc.Root.Element(XKey.clients).Elements(XKey.client)
// client object
// I cannot get ExpandoObject to initialize inline
select new ExpandoObject() { // try initialization syntax, COMPILE ERR
OnlineDetails = new
{
Password = client.Element(XKey.onlineDetails).
Element(XKey.password).Value,
Roles = client.Element(XKey.onlineDetails).
Element(XKey.roles).Elements(XKey.roleId).
Select(xroleid => xroleid.Value)
// More online detail fields TBD
},
// etc ....
// YIELD DYNAMIC OBJECTS BACK THROUGH IEnumerable<dynamic>...
foreach (var client in qClients) …Run Code Online (Sandbox Code Playgroud) 对于我的生活II似乎无法使数据绑定到Dynamics或ExpandoObjects工作.
我在WinForms和WebForms中尝试了这个,并在每个中得到不同的结果:
在ASP.NET中:
<asp:DropDownList ID="DropDownList1" runat="server">
</asp:DropDownList>
protected void Page_Load(object sender, EventArgs e)
{
dynamic contacts = new List<dynamic>();
contacts.Add(new ExpandoObject());
contacts[0].Name = "Patrick Hines";
contacts[0].Phone = "206-555-0144";
contacts.Add(new ExpandoObject());
contacts[1].Name = "Ellen Adams";
contacts[1].Phone = "206-555-0155";
DropDownList1.DataSource = contacts;
DropDownList1.DataTextField = "Name";
DropDownList1.DataBind();
}
Run Code Online (Sandbox Code Playgroud)
这导致:
DataBinding:'System.Dynamic.ExpandoObject'不包含名称为'Name'的属性.
在WinForms中,我有一个不同的问题:
dynamic contacts = new List<dynamic>();
contacts.Add(new ExpandoObject());
contacts[0].Name = "Patrick Hines";
contacts[0].Phone = "206-555-0144";
contacts.Add(new ExpandoObject());
contacts[1].Name = "Ellen Adams";
contacts[1].Phone = "206-555-0155";
this.departmentList.DataSource = contacts;
this.departmentList.DisplayMember = "Name";
Run Code Online (Sandbox Code Playgroud)
这导致ComboBox显示"System.Dynamic.ExpandoObject" - 因为它只是在集合中的两个项目上调用ToString().:( …
我有一个看起来像这样的WebMethod用于填充jqGrid
[System.Web.Script.Services.ScriptService]
public class MyWebService: System.Web.Services.WebService
{
[WebMethod]
[Authorize(Roles = "Admin")]
public object GetPeople(bool _search, double nd, int rows, int page, string sidx, string sord)
{
var tbl = new DynamicModel("ConnStr", tableName: "Person", primaryKeyField: "ID");
var results = tbl.Paged(orderBy: sidx + " " + sord, currentPage: page, pageSize: rows);
return results;
}
}
Run Code Online (Sandbox Code Playgroud)
"results"是一个System.Dynamic.ExpandoObject,其属性为Items,TotalPages,TotalRecords
我从webservice上回来的json看起来像这样
{
"d": [{
"Key": "TotalRecords",
"Value": 1
}, {
"Key": "TotalPages",
"Value": 1
}, {
"Key": "Items",
"Value": [
[{
"Key": "Row",
"Value": 1
}, …Run Code Online (Sandbox Code Playgroud) 我有一个包含ExpandoObjects字典的列表.我将此绑定到网格,但现在我想对列表进行排序.
var rows = new List<dynamic>();
for (int i = 0; i < 1000; i++)
{
dynamic expandy = new ExpandoObject();
var dictionary = (IDictionary<string, object>)expandy;
dictionary.Add("ID", i);
dictionary.Add("Name", "Name" + i);
rows.Add(dictionary);
}
Run Code Online (Sandbox Code Playgroud)
那么看看上面的测试代码我如何排序(升序或降序)说"ID"或"名称"或我动态添加的任何其他属性?
更多信息,我希望像这样排序(这不起作用);
var newOrder = from r in rows
orderby ("Name") ascending
select r;
Run Code Online (Sandbox Code Playgroud) 我想知道是否可以使用常规LINQ查询ExpandoObject?原因是我有动态ExpandoObject但我需要先进行一些查询才能进一步传递.
它有一些永远保留的属性Id,Notes但也有一些我无法控制的动态属性.
这是我的列表看起来像
[
{
"Id": 1,
"FileId": 1,
"Notes": "",
"1": "12.02.1991"
},
{
"Id": 2,
"FileId": 2,
"Notes": "",
"1": "12.02.1991"
}
]
Run Code Online (Sandbox Code Playgroud)
如您所见,我有静态项目,然后确保每个项目动态键都成为该项目属性.在这个例子中1是关键而且12.02.1991是价值
var generatedItems = new List<object>();
foreach (var item in items)
{
var modifiedItem = new List<KeyValuePair<string, object>>
{
new KeyValuePair<string, object>("Id", item.Id),
new KeyValuePair<string, object>("FileId", item.FileId),
new KeyValuePair<string, object>("Notes", item.Notes)
};
modifiedItem.AddRange(item.Fields.Select(field => new KeyValuePair<string, object>(field.Key, field.Value)));
generatedItems.Add(ConvertToExpandoObjects(modifiedItem)); // Here I construct object from …Run Code Online (Sandbox Code Playgroud) 我有一些函数,其原型看起来像这样:
public void doThings(string sql, dynamic dParams);
它使用这些参数进行某种SQL查询.我没有写它,但我必须使用它.当我做这样的事情时它工作正常:
doThings("select * from SomeTable where myval1=@v1 and myval2=@v2",
new
{
v1 = new Dapper.DbString()
{
Value = "yay",
IsAnsi = true,
Length = 50
},
v2 = new Dapper.DbString()
{
Value = "really",
IsAnsi = true,
Length = 32
}
});
Run Code Online (Sandbox Code Playgroud)
但是当我第一次将动态参数放入ExpandoObject时:
dynamic dynParams = new ExpandoObject();
dynParams.v1 = new Dapper.DbString()
{
Value = "yay",
IsAnsi = true,
Length = 50
}
doThings("query here", dynParams);
Run Code Online (Sandbox Code Playgroud)
然后查询不返回任何结果.我不想打电话doThings()和写new块十倍十个不同的场景,我可能要查询myval2或 …
我想使用ExpandoObject作为类型的Razor视图的viewmodel ViewPage<dynamic>.我这样做时出错了
ExpandoObject o = new ExpandoObject();
o.stuff = new { Foo = "bar" };
return View(o);
Run Code Online (Sandbox Code Playgroud)
我该怎么做才能使这项工作?
我正在使用DynamicObject的自定义实现,它非常适合我的应用程序,除了我遇到一些性能问题.在动态方面可以预期一些性能开销,但即使使用ExpandoObject,我也会看到显着的(读取:数量级)性能损失.
我不能使用ExpandoObject的原因是我想要覆盖它的一些行为.我把问题归结为下面一个非常简单的例子.
我的自定义ExpandoObject代码如下(简化为足以显示问题的代码) -
public class SuperExpando : DynamicObject
{
public Dictionary<string, object> dictionary = new Dictionary<string, object>();
public override bool TrySetMember(SetMemberBinder binder, object value)
{
dictionary[binder.Name] = value;
return true;
}
}
public dynamic m = new SuperExpando();
Run Code Online (Sandbox Code Playgroud)
当我在DynamicObject的字典直接设定值(iemdictionary ["键名"] = 500),那么我看到类似ExpandoObject,其是亚毫秒时间设置在字典中的密钥的值的性能.当我使用TrySetMember覆盖(iemkeyname = 500)时,我看到性能下降到30ms - 每个键值设置50ms.写入大量密钥时,这显然会成为一个问题.即使我一遍又一遍地写同一个密钥,通过TrySetMember访问它也需要相同的时间.
我的真实性能问题似乎与我使用动态的事实无关,因为它会影响TrySetMember.对于踢,我甚至评论了
dictionary[binder.Name] = value;
Run Code Online (Sandbox Code Playgroud)
在TrySetMember方法中,除了"return true;"之外什么都没有,而且性能是一样的.
如果我在SuperExpando类中添加如下内容 -
public override bool TryGetMember(GetMemberBinder binder, out object result)
{
if (dictionary.ContainsKey(binder.Name))
{
result = dictionary[binder.Name];
return true;
}
return false;
}
Run Code Online (Sandbox Code Playgroud)
通过TryGetMember访问(读取)变量的性能问题是相同的,而直接读取字典提供了合理的性能.
有任何想法吗?
-BJ奎因
编辑:这是完整的示例代码.只需创建一个表单并在其上放置一个运行go_Click事件的按钮,并将您的项目设置为控制台应用程序.对我来说,在ExpandoObject中设置所有50个键需要大约30ms,而SuperExpando至少需要750ms. …
我使用以下方法将我的大多数API JSON结果转换为对象:
public void ExpandoObject()
{
var sampleDATA = Sample.Create();
var json = JsonConvert.SerializeObject(sampleDATA);
var expConverter = new ExpandoObjectConverter();
dynamic obj = JsonConvert.DeserializeObject<ExpandoObject>(json, expConverter);
var a = obj.A;
var b = obj.B;
var c = obj.C; //and so on...
}
Run Code Online (Sandbox Code Playgroud)
但是,我遇到了这种JSON格式的奇怪情况......
[
{
"id": 42,
"name": "example name",
"member_count": 42,
"created_date": "example created_date",
"last_update": "example last_update",
"last_reset": "example last_reset"
}
]
Run Code Online (Sandbox Code Playgroud)
因为它是一个数组,我如何访问这些项,ExpandoObject应该是一个类别的IDictionary.
有人有这方面的经验吗?
如果我有这样的 ExpandoObject:
dynamic d = new ExpandoObject();
d.x = "a";
d.y = "b";
Run Code Online (Sandbox Code Playgroud)
并使用 JsonFormatter 将 Serilog 记录到 RollingFile,如下所示:
_logger.Debug("{@d}", d);
Run Code Online (Sandbox Code Playgroud)
它将被序列化为 json,如下所示:
[{"_typeTag":"KeyValuePair`2","Key":"x","Value":"a"},{"_typeTag":"KeyValuePair`2","Key":"y","Value":"b"}]
Run Code Online (Sandbox Code Playgroud)
如果我使用 Newtonsoft.Json 序列化相同的 ExpandoObject,如下所示:
JsonConvert.SerializeObject(d)
Run Code Online (Sandbox Code Playgroud)
我会得到这个:
{"x":"a","y":"b"}
Run Code Online (Sandbox Code Playgroud)
如何使 Serilog 生成与 Newtonsoft.Json 相同的 json?
expandoobject ×10
c# ×5
dynamic ×4
json ×3
.net ×1
asmx ×1
asp.net ×1
data-binding ×1
json.net ×1
linq ×1
linq-to-xml ×1
razor ×1
serilog ×1
sql ×1