【问题标题】:Table Splitting with Entity Framework Core. Flatten Table to Master-Detail使用 Entity Framework Core 进行表拆分。将表展平为主-详细信息
【发布时间】:2019-04-30 09:43:02
【问题描述】:

我想把这个扁平化的表放到类级别的主从层次结构中

| Type | DateTime   | Value |
-----------------------------
| 4711 | 2018-01-01 |  0.7  |
| 4711 | 2018-01-02 |  0.8  |
| 4711 | 2018-01-03 |  0.9  |
| 4711 | 2018-01-04 |  1.0  |
| 4712 | 2018-01-01 |  3.2  |
| 4712 | 2018-01-02 |  2.7  |
| 4712 | 2018-01-03 |  5.6  |
| 4712 | 2018-01-04 |  1.9  |

类结构

[Table("TypeValues")]
public class TypeMaster
{
    [Column("Type")]
    public int Type { get; set; }

    [ForeignKey("Type")]
    public virtual ICollection<TypeValue> Values { get; set; }
}

[Table("TypeValues")]
public class TypeValue
{
    [Column("DateTime")]
    public DateTime TimeStamp { get; set; }

    [Column("Value")]
    public float? Value { get; set; }

    public TypeMaster Index { get; set; }
}

我已经尝试了基于类型和日期时间的复合键之间的几种变体,但每次都有新的挑战阻止我完成这个简单的任务。我已经不知道了。

最后我不希望有像类型这样的冗余数据。我想要按该类型分组的数据。

{
  "Result": [
    {
      "Type": "4711",
      "Values": [
        {
          "TimeStamp": "2018-01-01",
          "Value": "0.7"
        },
        {
          "TimeStamp": "2018-01-02",
          "Value": "0.8"
        },
        {
          "TimeStamp": "2018-01-03",
          "Value": "0.9"
        },
        {
          "TimeStamp": "2018-01-04",
          "Value": "1.0"
        }
      ]
    },
    {
      "Type": "4712",
      "Values": [
        {
          "TimeStamp": "2018-01-01",
          "Value": "3.2"
        },
        {
          "TimeStamp": "2018-01-02",
          "Value": "2.7"
        },
        {
          "TimeStamp": "2018-01-03",
          "Value": "5.6"
        },
        {
          "TimeStamp": "2018-01-04",
          "Value": "1.9"
        }
      ]
    }
  ]
}

更新

为了说明这一点。我需要一个可以将 IQueryable 转发到以下服务的解决方案。解决方案不是手动对数据进行分组,而是使用 List。

所以我需要在模型级别解决这个问题。

【问题讨论】:

  • 只使用GroupBy(x=&gt;x.Type) here
  • 表拆分不能用于规范化不良的数据模型。
  • 对不起,我忘了说这是不可能的。我需要通过设计类和使用模型构建器来做到这一点
  • @GertArnold:好的,我还有哪些其他选择?
  • @masterchris_99 表拆分用于一对一关系。您的 only 选项是使用查询 (GroupBy)。您无法在模型级别解决它。

标签: c# asp.net .net database entity-framework


【解决方案1】:

这段代码会起作用吗?

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;

namespace ConsoleApplication86
{
    class Program
    {
        static void Main(string[] args)
        {
            DataTable dt = new DataTable();
            dt.Columns.Add("Type", typeof(int));
            dt.Columns.Add("DateTime", typeof(DateTime));
            dt.Columns.Add("Value", typeof(float));

            dt.Rows.Add(new object[] {4711, DateTime.Parse("2018-01-01"), 0.7 });
            dt.Rows.Add(new object[] {4711, DateTime.Parse("2018-01-02"), 0.8 });
            dt.Rows.Add(new object[] {4711, DateTime.Parse("2018-01-03"), 0.9 });
            dt.Rows.Add(new object[] {4711, DateTime.Parse("2018-01-04"), 1.0 });
            dt.Rows.Add(new object[] {4712, DateTime.Parse("2018-01-01"), 3.2 });
            dt.Rows.Add(new object[] {4712, DateTime.Parse("2018-01-02"), 2.7 });
            dt.Rows.Add(new object[] {4712, DateTime.Parse("2018-01-03"), 5.6 });
            dt.Rows.Add(new object[] {4712, DateTime.Parse("2018-01-04"), 1.9 });

            var groups = dt.AsEnumerable().GroupBy(x => x.Field<int>("Type")).ToList();

            List<TypeMaster> data = (from g in groups
                                     select new { grp = new TypeMaster() { Type = g.Key }, rows = g })
                       .Select(x => new TypeMaster() {
                           Type = x.grp.Type,
                           Values = x.grp.Values = x.rows.Select(y => new TypeValue() {
                                   TimeStamp = y.Field<DateTime>("DateTime"),
                                   Value = y.Field<float>("Value"),
                                   Index = x.grp
                               }).ToList()
                       }).ToList();


         }

    }

    [Table("TypeValues")]
    public class TypeMaster
    {
        [Column("Type")]
        public int Type { get; set; }

        [ForeignKey("Type")]
        public virtual ICollection<TypeValue> Values { get; set; }
    }

    [Table("TypeValues")]
    public class TypeValue
    {
        [Column("DateTime")]
        public DateTime TimeStamp { get; set; }

        [Column("Value")]
        public float? Value { get; set; }

        public TypeMaster Index { get; set; }
    }




}

【讨论】:

  • 这与实体框架无关。这是一个简单的分组依据。我需要返回 IQueryable。在您的情况下,执行 SQL 语句,转换为列表,然后返回。因此,所有进一步的过滤器都将对已加载到内存中的数据执行
  • @jdweng 你为什么要通过问另一个问题来回答一个问题,然后是无法解释的代码?未来的读者不会花精力去深入研究代码并找到回答问题的相关部分。这就是为什么“试试这个”的答案(实际上是这个)不是很有用。最好突出答案的本质。我认为本质是:将分组投影到大师班。正如 Ivan 上面所说,这很可能是一个可以进一步扩展的IQueryable。我认为DataTable 部分只是令人困惑。
  • 如何在没有输入的情况下测试代码?我的解决方案是回答关于“Flatten DataTable to Classes”的 OP 问题。我没有“Master-Detail”应用程序,无法使用 OPs Environment 进行测试,这就是我说“TRY”的原因。我不知道 OP 是否需要进行更改才能在他的环境中工作。
猜你喜欢
  • 1970-01-01
  • 2020-08-28
  • 2021-04-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-10-19
  • 1970-01-01
相关资源
最近更新 更多