Проблема производительности в типе IEnumerable при запросе большого объема данных с помощью LINQ - PullRequest
0 голосов
/ 21 ноября 2018

Я использую LINQ для выполнения запроса к переменной типа List с большим объемом данных (более миллиона).В целях повышения производительности я использую IEnumerable для хранения результатов, но при попытке получить к нему небольшую задержку.

В частности, я хочу посмотреть, дал ли запрос какие-либо результаты, но когда я использую .Count() или .Any () снижает производительность.

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

Это то, что я пытаюсь запустить.

IEnumerable<Entity> matchingEntities = entities.Where(e => e.Names.Any(n => myEntity.Names.Any(entityName => entityName.CompareNameObjects(n))));

и вот мои классы

public class Entity
{
   public string EntityIdentifier { get; set; }
   public List<Name> Names { get; set; }
}

public class Name
{
    public string FullName { get; set; }
    public string NameType { get; set; }

    public bool CompareNameObjects(Name name2)
    {
        return FullName == name2.FullName &&
               NameType == name2.NameType;
    }
}

entity - это список всех моих объектов, и я хочу проверить, имеет ли myEntity какие-либо Имена, идентичные другим объектам в наборе.

РЕДАКТИРОВАНИЕ:

Структура данных аналогична двум классам (сущность и имя).Сущности создаются путем выбора всех сущностей вместе с их именами из базы данных в формате XML, а затем я преобразую XML в список следующим образом:

List<Entity> entities = new List<Entity>();
using (SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["myCS"].ConnectionString))
{
    conn.Open();
    SqlCommand cmd = new SqlCommand("GetAllEntities", conn);
    cmd.CommandType = CommandType.StoredProcedure;

    string entitiesXml = "";
    using (SqlDataReader rdr = cmd.ExecuteReader())
    {
        while (rdr.Read())
        {
            entitiesXml += rdr["XmlString"].ToString();
        }
    }

    using (TextReader reader = new StringReader(entitiesXml))
        entities = (Entity)xmlSerializer.Deserialize(reader);

    conn.Close();
}

GetAllEntities (Stored Procedure):
declare @xmlString nvarchar(max) =(
    select  e.EntityIdentifier,
        (
            select  n.[Full Name]  as 'FullName', 
                    n.[Name Type]  as 'NameType'
            from tblNames n
            where e.EntityID=n.[Entity_ID]
            for xml path('Name'), type
        )
    from tblEntities e 
    order by e.EntityID
    for xml path('Entity')
) 
select @xmlString as XmlString

1 Ответ

0 голосов
/ 22 ноября 2018

По сути, вам следует избегать получения всех данных из вашей базы данных, а затем фильтровать их с помощью кода C #.Это требует больших усилий.

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

 // Let's say you have myEntity here
 var myEntity = new Entity();
 var entities = new List<Entity>();

 // You should prepare the list of name that you wanna to find before you do it so that you don't have to make it repeatedly for every iteration
 var names = myEntity.Names.Select(p=> p.FullName + p.NameType ).ToDictionary(p=>p, p=>p);

 IEnumerable<Entity> matchingEntities = entities.Where(e => e.Names.Any(n => names.ContainsKey(n.FullName + n.NameType)));

Это всего лишь пример, который может датьтебе больше идея.Вы можете улучшить намного больше.Я надеюсь, что это может помочь вам

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...