2015-10-20 4 views
0

У меня возникают проблемы с Servicestack и OrmLite в сценариях с высокой загрузкой данных.Servicestack - Ormlite - загрузка больших объемов данных

В частности,
1. У меня есть список 1000 000 + лиц
2. Я хотел бы, чтобы вставить их в Db (с помощью SQL Server), если запись не существует еще

Таким образом,

public class Entity 
{ 
    [Autoincrement] 
    public int Id {get;set;} 
    public string Name {get;set;} 
    public string Address {get;set;} 
} 

Теперь для логики импорта,

List<Entity> entities = oneMillionEntities.ToList(); 
foreach (var entity in entities) 
{ 
    if (!db.Exists<Entity>(ar => ar.Address == entity.Address)) 
    { 
     db.Save(entity); 
    } 
} 

Проблема в том, что довольно часто дб все еще занят сохранением действия, поэтому db.Exists не всегда дает правильный результат. Каков наилучший способ обработки этих сценариев?

+0

Не могли бы вы уточнить, что вы подразумеваете под «БД по-прежнему занят сохранить действие»? Вы делаете что-то асинхронно и получаете блокировки чтения или записи? – PatrickSteele

+0

Как читать или писать блокировки ... Есть ли лучший способ сделать это? Или обработка блокировок db ... –

+1

Лично, с необходимостью обрабатывать 1 000 000 элементов, я бы, вероятно, НЕ использовал OrmLite. ORM отлично подходят для операций CRUD, но для массовых операций вы можете получить потрясающую скорость, используя 'SqlBulkCopy'. – PatrickSteele

ответ

1

Попробуйте

// Prepare SqlExpression 
var ev = Db.From<Entity>().Select(p => p.Address).GroupBy(p => p.Address); 

// Execute SqlExpression and transform result to HashSet 
var dbAddresses = Db.SqlList(ev).ToHashSet(); 

// Filter local entities and get only local entities with different addresses 
var filteredEntities = oneMillionEntities.Where(p => 
!dbAddresses.Contains(p.Address)); 

// Bulk insert 
db.InsertAll(filteredEntities.ToList()); 
+0

Это вставляет все элементы в список - это не то, что хотел OP. Он выполняет проверку адреса и только вставляет элементы с адресом, который не существует в базе данных. – PatrickSteele

+0

Приведенный здесь пример показывает, что один вызов метода лучше одного миллиона. Поэтому он может фильтровать список сущностей до и передать фильтрованный вид методу InsertAll. – labilbe

Смежные вопросы