4

我有 N 个数据表,其中 N-1 个数据表代表一些实体,1 个代表这些实体之间的关系。

实体国家

Country DATATABLE

ID    | Country Name | Country Code
------------------------------------
ID1   | USA          | USA
ID2   | INDIA        | IND
ID3   | CHINA        | CHI

实体大陆

Continent DATATABLE

ID     | Continent Name | Continent Code
------------------------------------
IDC1   | NORTH AMERICA  | NA
IDC2   | SOUTH AMERICA  | SA
IDC3   | ASIA           | AS

实体公司

Company DATATABLE

ID    | Company Name   | Company Code
------------------------------------
CM1   | XYZ Company    | XYZ
CM2   | Fun Company    | Fun
CM3   | ABC Company    | ABC

这些之间的关系。

Company_Country_Continent_Relationship DataTable 

ID    | Company        | Country    |  Continent     | Some Value1     | Some Value 2
-------------------------------------------------------------------------------------
R1    | CM1            | ID1        |  IDC1          | 100             | 150
R2    | CM2            | ID2        |  IDC3          | 200             | 200
R3    | CM3            | ID1        |  IDC1          | 150             | 250
R4    | CM1            | ID3        |  IDC3          | 100             | 150
R5    | CM2            | ID1        |  IDC1          | 200             | 200
R6    | CM3            | ID2        |  IDC3          | 150             | 250
R7    | CM1            | ID2        |  IDC3          | 100             | 150
R8    | CM2            | ID3        |  IDC3          | 200             | 200
R9    | CM3            | ID3        |  IDC3          | 150             | 250

现在我需要生成另一个关系表,它将保存名称而不是 ID。在此示例中,关系数据存储公司、国家和大陆的 ID,现在我想将这些 id 值转换为名称,即。代替或 CM1 - XYZ 公司。

对于这种转换,我使用了一种方法TramnsformRelationshipData,并且它工作正常。

    public static DataTable TramnsformRelationshipData(DataTable relationshipData, Dictionary<string, DataTable> mapping)
    {
        DataTable transformedDataTable = null;
        if (relationshipData == null || mapping == null )
           return null;

        transformedDataTable = relationshipData.Copy();

        foreach (DataColumn item in relationshipData.Columns)
        {
            if (mapping.ContainsKey(item.ColumnName))
            {
                var instanceData = mapping[item.ColumnName];
                if (instanceData == null)
                    return null;

                foreach (DataRow row in transformedDataTable.Rows)
                {
                    var filteredRows = instanceData.Select("ID = '" + row[item.ColumnName] + "'");
                    if (filteredRows.Any())
                        row[item.ColumnName] = filteredRows[0][1];
                }
            }
        }

        return transformedDataTable;
    }

但是,这种方法迭代所有数据表,并且当关系数据有更多实体要转换时非常慢。那么,我该如何优化此代码,以处理具有大量行的大量数据表。

编辑:在大多数情况下,这些数据不存储在数据库中,这些数据在内存中,并且在内存中,这些数据表的计数可以增加或减少。

谢谢。

4

3 回答 3

3

SELECT INTO您是否考虑过使用语句创建 SQL 代码(这将比使用 C# 代码快得多) ?当我需要处理大量数据时,我通常更喜欢使用 SQL。

示例取自此 MSDN页面。

SELECT c.FirstName, c.LastName, e.JobTitle, a.AddressLine1, a.City, sp.Name AS [State/Province], a.PostalCode
INTO dbo.EmployeeAddresses
FROM Person.Person AS c JOIN HumanResources.Employee AS e ON e.BusinessEntityID = c.BusinessEntityID
JOIN Person.BusinessEntityAddress AS bea ON e.BusinessEntityID = bea.BusinessEntityID
JOIN Person.Address AS a ON bea.AddressID = a.AddressID
JOIN Person.StateProvince as sp ON sp.StateProvinceID = a.StateProvinceID;

首先写一个SELECT语句来获取你的数据,然后添加INTO语句。

或者,您可以在用户INSERTSELECT位置指定要插入数据的列列表。示例取自MSDN页面。

INSERT INTO Production.ZeroInventory (DeletedProductID, RemovedOnDate)
SELECT ProductID, GETDATE() FROM ...
于 2012-08-17T07:40:29.070 回答
2

在我看来问题本身非常简单,如果您使用 sql,3 个连接可以解决它。
我猜源不在 sql 中(如果是的话,我会建议在那里创建一个视图以获得最佳性能)。
如果您必须使用数据集,您可以使用 linq 来模拟连接。

检查此链接以了解如何将 linq 与数据集一起使用。您可以在此处
了解如何加入最终结果将如下所示:

var q = from r in relations.AsEnumerable()
        join c in countries.AsEnumerable() on r.Country equals c.Id
        join con in continents.AsEnumerable() on r.Continent equals con.Id
        select new { someval = r.someValue1, 
                     someval2 = r.someValue2, 
                     countryname = c.Name 
                     continent = con.Name}; 
于 2012-08-17T07:50:13.527 回答
2

这里的解决方案是创建一个基于哈希的集合(即哈希表、字典、.NET 中的查找),其中 ID 列是键并使用它而不是 .Select(Id = x)

代码可能看起来像这样......未经测试。

public static DataTable TramnsformRelationshipData(DataTable relationshipData, Dictionary<string, DataTable> mapping) 
    { 
        Dictionary<string,Dictionary<string,DataRow>> newMappings = new Dictionary<string,Dictionary<string,DataRow>>();
        foreach (var kvp in mapping)
        {
            newMappings.Add(kvp.Key,kvp.Value.Rows.Cast<DataRow>().ToDictionary(dr=>dr["ID"] as string));
        }

        DataTable transformedDataTable = null; 
        if (relationshipData == null || mapping == null ) 
           return null; 

        transformedDataTable = relationshipData.Copy(); 

        foreach (DataColumn item in relationshipData.Columns) 
        { 
            if (newMapping.ContainsKey(item.ColumnName)) 
            { 
                var instanceData = newMapping[item.ColumnName]; 
                if (instanceData == null) 
                    return null; 

                foreach (DataRow row in transformedDataTable.Rows) 
                { 
                //  var filteredRows = instanceData.Select("ID = '" + row[item.ColumnName] + "'"); 
                //  if (filteredRows.Any()) 
                    row[item.ColumnName] = instanceData[row[item.ColumnName]][1];                       
                } 
            } 
        } 

        return transformedDataTable; 
    } 
于 2012-08-23T16:31:57.333 回答