- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
(这是为您提供围绕我的问题的背景信息。您可以跳到“问题”并阅读该内容,然后如果您想直接进入主题,则可以返回并浏览背景知识.抱歉,这是一面文字墙!)
<小时/>我需要将一堆非常非常糟糕的 JSON 存储在数据库中。本质上,某人获取了一个大型 XML 文件,并通过简单地使用 XML 的 XPath 将其序列化为一个大型、扁平的 JSON 对象。这是我的意思的一个例子:
原始 XML:
<statistics>
<sample>
<date>2012-5-10</date>
<duration>11.2</duration>
</sample>
<sample>
<date>2012-6-10</date>
<duration>13.1</duration>
</sample>
<sample>
<date>2012-7-10</date>
<duration>10.0</duration>
</sample>
</statistics>
<小时/>
我必须使用的可怕的 JSON:(基本上只是上面的 XPath)
{
"statistics":"",
"statistics/sample":"",
"statistics/sample/date":"2012-5-10",
"statistics/sample/duration":"11.2",
"statistics/sample@1":"",
"statistics/sample/date@1":"2012-6-10",
"statistics/sample/duration@1":"13.1",
"statistics/sample@2":"",
"statistics/sample/date@2":"2012-7-10",
"statistics/sample/duration@2":"10.0",
}
现在我需要将其放入包含 statistics
的数据库中表 date
和duration
列。
我目前是如何做的:(或者至少是一个简单的例子)
Tuple<string, string>[] jsonToColumn = // maps JSON value to SQL table column
{
new Tuple<string, string>("statistics/sample/date", "date"),
new Tuple<string, string>("statistics/sample/duration", "duration")
};
// Parse the JSON text
// jsonText is just a string holding the raw JSON
JavaScriptSerializer serializer = new JavaScriptSerializer();
Dictionary<string, object> json = serializer.DeserializeObject(jsonText) as Dictionary<string, object>;
// Duplicate JSON fields have some "@\d+" string appended to them, so we can
// find these and use them to help uniquely identify each individual sample.
List<string> sampleIndices = new List<string>();
foreach (string k in json.Keys)
{
Match m = Regex.Match(k, "^statistics/sample(@\\d*)?$");
if (m.Success)
{
sampleIndices .Add(m.Groups[1].Value);
}
}
// And now take each "index" (of the form "@\d+" (or "" for the first item))
// and generate a SQL query for its sample.
foreach (string index in compressionIndices)
{
List<string> values = new List<string>();
List<string> columns = new List<string>();
foreach (Tuple<string, string> t in jsonToColumn)
{
object result;
if (json.TryGetValue(t.Item1 + index, out result))
{
columns.Add(t.Item2);
values.Add(result);
}
}
string statement = "INSERT INTO statistics(" + string.Join(", ", columns) + ") VALUES(" + string.Join(", ", values) + ");";
// And execute the statement...
}
但是,我想使用 ADO.NET 实体数据模型(或类似 LINQ 的东西)而不是这种黑客技术,因为我需要在插入和应用一些更新以及创建和执行我的数据之前开始执行一些查询。自己的 SQL 语句只是……很麻烦。我创建了一个 ADO.NET 实体数据模型 (.edmx) 文件并进行了设置,现在我可以轻松地使用此模型与数据库交互并向数据库写入数据。
<小时/>问题/问题
问题是我不确定如何最好地从 JSON 映射到 ADO.NET 实体数据模型 Statistic
对象(代表 statistics
表中的样本/记录)。最简单的就是改变我的 Tuple
list 来使用诸如指向成员的指针之类的东西(就像 Tuple<string, Statistic::*Duration>("statistics/sample/duration", &Statistic::Duration)
如果这是 C++),但是 a) 我什至不认为这在 C# 中是可能的,b) 即使它是我的 Tuple
都有不同的类型。
我在这里有哪些选择?如何最好地将 JSON 映射到我的 Statistic
物体?我对 LINQ 世界有点陌生,想知道是否有一种方法(通过 LINQ 或其他方式)来映射这些值。
这是我所处的次优位置(使用如此糟糕的 JSON),并且我认识到,考虑到我的情况,我当前的方法可能比其他任何方法都要好,如果是这种情况,我什至会接受这就是我的答案。但我真的很想探索有哪些选项可以将此 JSON 映射到 C# 对象(并最终映射到 SQL 数据库)。
最佳答案
如果整个问题是将您必须的“JSON”映射到 POCO 实体,这里有一个关于如何使用自定义 JavascriptConverter
反序列化它的示例:
您的 POCO 实体:
public class Statistics
{
public Statistics()
{
Samples = new List<Sample>();
}
public List<Sample> Samples { get; set; }
}
public class Sample
{
public DateTime Date { get; set; }
public float Duration { get; set; }
}
您的统计转换器:
public class StatsConverter : JavaScriptConverter
{
public override object Deserialize(IDictionary<string, object> dictionary, Type type, JavaScriptSerializer serializer)
{
if (dictionary == null)
throw new ArgumentNullException("dictionary");
else if (type == typeof(Statistics))
{
Statistics statistics = null;
Sample sample = null;
{
foreach (var item in dictionary.Keys)
{
if (dictionary[item] is string && item.Contains("duration"))
sample.Duration = float.Parse(dictionary[item].ToString());
else if (dictionary[item] is string && item.Contains("date"))
sample.Date = DateTime.Parse((dictionary[item].ToString()));
else if (dictionary[item] is string && item.Contains("sample"))
{
sample = new Sample();
statistics.Samples.Add(sample);
}
else if (dictionary[item] is string && item.Contains("statistics"))
statistics = new Statistics();
}
}
return statistics;
}
return null;
}
public override IDictionary<string, object> Serialize(object obj, JavaScriptSerializer serializer)
{
throw new NotImplementedException();
}
public override IEnumerable<Type> SupportedTypes
{
get { return new ReadOnlyCollection<Type>(new List<Type>(new Type[] { typeof(Statistics)})); }
}
}
现在是有关如何反序列化它的示例:
string json = @"{
""statistics"":"""",
""statistics/sample"":"""",
""statistics/sample/date"":""2012-5-10"",
""statistics/sample/duration"":""11.2"",
""statistics/sample@1"":"""",
""statistics/sample/date@1"":""2012-6-10"",
""statistics/sample/duration@1"":""13.1"",
""statistics/sample@2"":"""",
""statistics/sample/date@2"":""2012-7-10"",
""statistics/sample/duration@2"":""10.0""
}";
//These are the only 4 lines you'll require on your code
JavaScriptSerializer serializer = new JavaScriptSerializer();
StatsConverter sc = new StatsConverter();
serializer.RegisterConverters(new JavaScriptConverter[] { new StatsConverter() });
Statistics stats = serializer.Deserialize<Statistics>(json);
上面的
stats
对象将反序列化为 Statistics
对象,其 Samples
集合中有 3 个 Sample
对象。
关于c# - 如何将字符串/不良 JSON 映射到 C# 对象成员? (最终到 MySQL 数据库),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12206777/
如何使用 SPListCollection.Add(String, String, String, String, Int32, String, SPListTemplate.QuickLaunchO
我刚刚开始使用 C++ 并且对 C# 有一些经验,所以我有一些一般的编程经验。然而,似乎我马上就被击落了。我试过在谷歌上寻找,以免浪费任何人的时间,但没有结果。 int main(int argc,
这个问题已经有答案了: In Java 8 how do I transform a Map to another Map using a lambda? (8 个回答) Convert a Map>
我正在使用 node + typescript 和集成的 swagger 进行 API 调用。我 Swagger 提出以下要求 http://localhost:3033/employees/sear
我是 C++ 容器模板的新手。我收集了一些记录。每条记录都有一个唯一的名称,以及一个字段/值对列表。将按名称访问记录。字段/值对的顺序很重要。因此我设计如下: typedef string
我需要这两种方法,但j2me没有,我找到了一个replaceall();但这是 replaceall(string,string,string); 第二个方法是SringBuffer但在j2me中它没
If string is an alias of String in the .net framework为什么会发生这种情况,我应该如何解释它: type JustAString = string
我有两个列表(或字符串):一个大,另一个小。 我想检查较大的(A)是否包含小的(B)。 我的期望如下: 案例 1. B 是 A 的子集 A = [1,2,3] B = [1,2] contains(A
我有一个似乎无法解决的小问题。 这里...我有一个像这样创建的输入... var input = $(''); 如果我这样做......一切都很好 $(this).append(input); 如果我
我有以下代码片段 string[] lines = objects.Split(new string[] { "\r\n", "\n" }, StringSplitOptions.No
这可能真的很简单,但我已经坚持了一段时间了。 我正在尝试输出一个字符串,然后输出一个带有两位小数的 double ,后跟另一个字符串,这是我的代码。 System.out.printf("成本:%.2
以下是 Cloud Firestore 列表查询中的示例之一 citiesRef.where("state", ">=", "CA").where("state", "= 字符串,我们在Stack O
我正在尝试检查一个字符串是否包含在另一个字符串中。后面的代码非常简单。我怎样才能在 jquery 中做到这一点? function deleteRow(locName, locID) { if
这个问题在这里已经有了答案: How to implement big int in C++ (14 个答案) 关闭 9 年前。 我有 2 个字符串,都只包含数字。这些数字大于 uint64_t 的
我有一个带有自定义转换器的 Dozer 映射: com.xyz.Customer com.xyz.CustomerDAO customerName
这个问题在这里已经有了答案: How do I compare strings in Java? (23 个回答) 关闭 6 年前。 我想了解字符串池的工作原理以及一个字符串等于另一个字符串的规则是
我已阅读 this问题和其他一些问题。但它们与我的问题有些无关 对于 UILabel 如果你不指定 ? 或 ! 你会得到这样的错误: @IBOutlet property has non-option
这两种方法中哪一种在理论上更快,为什么? (指向字符串的指针必须是常量。) destination[count] 和 *destination++ 之间的确切区别是什么? destination[co
This question already has answers here: Closed 11 years ago. Possible Duplicates: Is String.Format a
我有一个Stream一个文件的,现在我想将相同的单词组合成 Map这很重要,这个词在 Stream 中出现的频率. 我知道我必须使用 collect(Collectors.groupingBy(..)
我是一名优秀的程序员,十分优秀!