У меня есть Datatable с столбцами Id (guid) и Name (string). Я просматриваю таблицу данных и запускаю критерии проверки для имени (скажем, оно должно содержать только буквы и цифры), а затем добавляю соответствующий идентификатор в список, если имя проходит проверку.

Что-то вроде ниже: -

List<Guid> validIds=new List<Guid>();
foreach(DataRow row in DataTable1.Rows)
{
      if(IsValid(row["Name"])
        {
            validIds.Add((Guid)row["Id"]);
        }

}

В дополнение к этой проверке я также должен проверить, повторяется ли имя во всей таблице данных (даже с учетом регистра), если оно повторяется, мне не следует добавлять соответствующий идентификатор в список.

Вещи, о которых я думаю / думал: -

1) У меня может быть другой список, проверьте его на «Имя». Если оно существует, добавлю соответствующую гильдию 2) Я не могу использовать HashSet, так как это будет рассматривать «Test» и «test» как разные строки, а не как дубликаты. . 3) Переместите DataTable в другой, где у меня есть имена дисков (это я не пробовал, и код может быть неправильным, исправьте меня, когда это возможно)

DataTable dataTableWithDistinctName = new DataTable();
dataTableWithDistinctName.CaseSensitive=true
CopiedDataTable=DataTable1.DefaultView.ToTable(true,"Name");

Я бы перебрал исходный datatable и проверил наличие «Name» в CopiedDataTable. Если он существует, я не буду добавлять Id в список.

Есть ли лучший и оптимальный способ добиться того же? Мне нужно всегда думать о производительности. Хотя в SO есть много связанных вопросов, я не нашел проблемы, подобной этой. Если бы вы могли указать мне на вопрос, похожий на этот, это было бы полезно.

РЕДАКТИРОВАТЬ: - Количество записей может варьироваться от 2000 до 3000 .

Благодарность

0
Ashish Gupta 17 Мар 2010 в 13:41

2 ответа

Лучший ответ
    /* I did this entirely in SQL and avoided ADO.NET*/

    /*I Pass the CSV of valid object Ids and split that in a table*/

DECLARE @TableTemp TABLE        
(        
    TempId uniqueidentifier      
)        
INSERT INTO @TableTemp 
SELECT cast(Data AS uniqueidentifier )AS ID FROM dbo.Split1(@ValidObjectIdsAsCSV,',')    


/*Self join with table1 for any duplicate rows and update the column value*/    
UPDATE Table1 
SET IsValidated=1
FROM Table1 AS A INNER JOIN @TableTemp AS Temp
ON A.ID=Temp.TempId 
WHERE NOT EXISTS (SELECT Name,Count(Name) FROM Table1 
WHERE A.Name=B.Name
GROUP BY Name HAVING Count(Name)>1)
0
Ashish Gupta 23 Мар 2010 в 14:20

Если вы хотите предотвратить дублирование, это может быть изнурительной работой, и я не знаю, сколько записей вы имеете дело за раз ... Если небольшой набор, я бы подумал о выполнении запроса перед каждой попыткой вставки из вашего Источник LIVE на основе

select COUNT(*) as CountOnFile from ProductionTable where UPPER(name) = UPPER(name from live data).  

Если набор результатов CountOnFile> 0, не добавляйте.

Если вы имеете дело с большим набором данных, например с массовым импортом, я бы вытащил все данные во временную таблицу, а затем выполнил запрос, где NOT IN ... что-то вроде

create table OkToBeAdded as 
select distinct upper( TempTable.Name ) as Name, GUID
  from TempTable
  where upper( TempTable.Name ) 
      NOT IN ( select upper( LiveTable.Name )
                 from LiveTable
                 where upper( TempTable.Name ) = upper( LiveTable.Name )
             );

insert into LiveTable ( Name, GUID )
  select Name, GUID from OkToBeAdded;

Очевидно, что SQL является образцом, и его нужно будет скорректировать в зависимости от вашего конкретного внутреннего источника.

1
DRapp 17 Мар 2010 в 14:28
Количество записей может варьироваться от 2000 до 3000.
 – 
Ashish Gupta
17 Мар 2010 в 14:50
Тогда я бы пошел с опцией временной таблицы, чем счетчик (*) для каждой записи
 – 
DRapp
17 Мар 2010 в 16:08