【问题标题】:Join 3 datatables in c#在c#中加入3个数据表
【发布时间】:2017-01-01 15:13:25
【问题描述】:

我有以下 3 个数据表:

    Table1 
    --------------------------------
    ScheduleID | Name  | Details
    -----------------------------
    1             S1     schedule details 
    2             S2     schedule details
    3             S3     schedule details
    4             S4     schedule details


    Table2
    ------------------------------
    ScheduleGroupID  | ScheduleID 
    ------------------------------
    1                      1      
    1                      2    
    1                      3     
    2                      4     

    Table3
    -----------------------------------------------
    ScheduleGroupID   | Description  | ScheduleCount
    ------------------------------------------------
    1                    Urgent             3
    2                    Non-urgent         1


    Expected Result
    ---------------------------------------------------------------
    ScheduleID | Name | Details | ScheduleGroupID |   Description
    -------------------------------------------------------------
    1             S1       5             1         Urgent(row from table3) 
    2             S2       5             1         Urgent(row from table3) 
    3             S3       5             1         Urgent(row from table3) 
    4             S4       5             2         Non-urgent(from table3) 

所以我有三个数据表,并希望将它们合并到一个表中,以产生如上所示的预期结果。这如何在 c# 中完成?我想我必须使用 LINQ,但没有太多经验。

【问题讨论】:

  • 实体框架和 LINQ,你需要一个实体框架模型还是你已经这样做了?您将在表格上获得一个导航属性
  • @MarkHomer,他不需要,有很多方法都不需要,虽然这可能是最简单的
  • @MikeT 你能提供更多关于这些其他方式的信息吗,我正在尝试避免使用实体框架
  • @MikeT 不,他没有,但他为什么不呢?为什么不想使用实体框架?

标签: c# asp.net-mvc datatable dataset


【解决方案1】:

在表之间引入直接关系将使程序更容易检索数据。如果使用 EF,则可以通过写一行来检索结果。

以上表格可以更改为仅使用 2 个表格。 您可以在 table1 中添加另一列作为 schedulegroupID,这将是 schedulegroup 表的外键

ALTER TABLE dbo.schedule
ADD schedulegroupId INT

ALTER TABLE dbo.schedule
ADD CONSTRAINT FK_scheduleGroup
FOREIGN KEY (schedulegroupId)
REFERENCES scheduleGroup(ID)

通过这种方式,表之间将存在直接关系,从而更容易编写 SQL 和 LINQ 查询。

--SQL Query 
SELECT * FROM dbo.schedule s INNER JOIN dbo.scheduleGroup sg ON s.schedulegroupid = sg.ID
//LINQ Query    
var query = db.schedules.Include("scheduleGroup").ToList();

下面的代码将显示所需结果的第一行。

Console.WriteLine(query[0].Name.ToString() + "," +  query[0].Details.ToString() + "," +  query[0].schedulegroupId.Value.ToString() + ","
                + query[0].scheduleGroup.Description.ToString());

【讨论】:

  • 谢谢!我明白你的意思!我也相信,如果我改变了表或存储过程的编写方式,它一开始就不会带来这个问题,但这些是无法改变的。不过,我感谢您的反馈。如果您知道任何学习 LINQ 查询的好资源,请告诉我。
【解决方案2】:

你问的问题是两部分

首先连接数据库

正如你所说,你想避免 EnitiyFramework

其他一些选项是

  • LinqToSql:这将与 EF 非常相似,但没有 整个框架的开销

  • 如果你想回到更老的学校,你有数据集 可以配置为比通用的dataset

  • 更有用
  • 甚至更老派的SQLCommandsdatareaders

获得数据后

那么最好的查询方法是 LinqToObjects

var results = from a in Table1
              join b in Table2 on a.ID equals b.ID
              join c in Table3 on b.ID2 equals c.ID2
              //create a anonymous type or better if you want the results to persist create a normal object
              select new{ a.Column1, a.Column2, b.Column1, c.Column1};

你不能通过代码做到这一点 例如

//firstly build up a key index to make the matching easier
var t1Dic = new Dictionary<int,DataRow>();
foreach(var row in table1.Rows)
{
    t1Dic.Add(row[IDCol],row);
}
var t2Dic = new Dictionary<int,DataRow>();
foreach(var row in table2.Rows)
{
    t2Dic.Add(row[IDCol],row);
}
//next run though your linking table and add them to your results table
var results = new DataTable();
foreach(var row in table3.Rows)
{
    var r = results.NewRow();
    r[YourColumnName1] = t1Dic[row[Id1Col][YourColumnName1];
    r[YourColumnName2] = t1Dic[row[Id1Col][YourColumnName2];
    r[YourColumnName3] = t2Dic[row[Id2Col][YourColumnName3];
    r[YourColumnName4] = t2Dic[row[Id2Col][YourColumnName4];
    r[YourColumnName5] = t2Dic[row[Id2Col][YourColumnName5];
}

EF 和 Linq 绝对是最简单的方法

【讨论】:

  • 感谢 MikeT,如果只有 EF 是一个选项,但不幸的是,这次没有。下次遇到类似挑战时,我会考虑您的回答!非常感谢!
【解决方案3】:

假设它是DataTable,你可以这样join

    var result = from s in schedule.AsEnumerable()
    join sg in  schedulegroup.AsEnumerable() on s.Field<int>("ScheduleID") equals sg.Field<int>("ScheduleID") 
    join g in groups.AsEnumerable() on sg.Field<int>("ScheduleGroupID") equals g.Field<int>("ScheduleGroupID") 
    select new 
    {
        ScheduleID = s.Field<int>("ScheduleID"),
        Name = s.Field<string>("Name"),
        Details = s.Field<int>("Details"),
        ScheduleGroupID = sg.Field<int>("ScheduleGroupID"),
        Description = g.Field<string>("Description")
    };

查看Demo

【讨论】:

  • 这非常有效,是我实施的方法。
【解决方案4】:

你可以像下面这样创建一个类

public class TestClass
{
    public int ScheduleID { get; set; }
    public string Name { get; set; }
    public string Details { get; set; }
    public int ScheduleGroupID { get; set; }
    public string Description { get; set; }
}

然后像这样写查询

List<TestClass> colection = (from x in db.Table1
                join y in db.Table2 on x.ScheduleID  equals y.ScheduleID
                join z in db.Table3 on y.ScheduleGroupID equals z.ScheduleGroupID
                select new CityClass
                {
                   ScheduleID = x.ScheduleID,
                   Name = x.Name,
                   Details  = x.Details,
                   ScheduleGroupID = y.ScheduleGroupID,
                   Description = z.Description
                }).ToList();

【讨论】:

  • 感谢您的帮助!这行得通,您首先回复,因此已将您的回复标记为答案
猜你喜欢
  • 2012-07-04
  • 1970-01-01
  • 2018-02-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-10-27
  • 2018-01-19
相关资源
最近更新 更多