Использование массивов с asp.net и VB

#asp.net #vb.net #arrays

#asp.net #vb.net #массивы

Вопрос:

Извините, я уверен, что это то, что было рассмотрено много раз, но я не могу найти то, что мне нужно.

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

В любом случае, учитывая, что это одна запись, существует поле под названием «местоположения», это поле содержит следующие данные:

 locationName1,IpAddress|locationName2,IpAddress|etc
  

IP-адрес — это только первые 5 цифр IP-адреса, и он позволяет мне гарантировать, что логины для определенных элементов (раздел администратора, управляемый персоналом) могут приниматься только при подключении с компьютера компании (т. Е. С помощью нашего интернет-провайдера) — это в значительной степени ненужная функция, но останавливает детей, которых я использую для входа в системуглавная и прочее!

Итак, когда пользователь входит в систему, я могу проверить, действителен ли IP-адрес с помощью простого SQL-запроса.

 SELECT ips FROM settings WHERE loginLocations LIKE '%" amp; Left(ipAddress, 5) amp; " %'
  

Что мне нужно сделать сейчас, так это получить имя местоположения пользователя из массива данных.

Я придумал несколько длинных процедур цикла, но есть ли простой способ проанализировать

 locationName1,IpAddress1|locationName2,IpAddress2|etc
  

в виде строки и просто получаем LocationName, где LoginIp = IpAddressX

… или я делаю это совершенно нелепым образом и должен превратить его в XML-файл? (что затем создаст для вас целую кучу других вопросов о синтаксическом анализе XML !!)

Комментарии:

1. Какая версия . Какую сеть вы используете?

Ответ №1:

вы можете разделить строку на Vb.net и отправить его на запрос или что-нибудь в этом роде

 'Split the string on the "," character
    Dim parts As String() = s.Split(New Char() {","c})
  

Комментарии:

1. Спасибо. Я знаю, как разделить его, но как мне запросить это? Если я разделю его с помощью каналов, а затем проведу цикл, разделив его на запятую, я вижу, что мог бы создать циклическую настройку, которая могла бы ее найти, но это кажется затянутым для этой цели?

2. Вы можете отправить 3 или 4 IP-адреса процедуре в вашей БД и сделать что-то вроде: ГДЕ IPADDRESS IN (ip1, ip2, ip3). Знаете ли вы, как сделать подключение к вашему Sql?

3. Хм, я в порядке, запрашивая базу данных с помощью SQL, у меня возникла проблема, я думаю, запрашивая внутри поля. Эти данные, целая строка, хранятся в одном поле базы данных, называемом «местоположения», для каждого местоположения нет отдельной записи с полем IPAddress.

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

5. Я понимаю. Не могу отделаться от мысли, что я должен просто преобразовать свои данные настроек в XML-документ <locations><location1><LocationName>name</LocationName><locationIP>12.12</locationIP><location2> и т.д… Единственная проблема в том, что я мало что знаю об использовании XML в качестве источника данных и запросов с помощью XML

Ответ №2:

В SQL Server это функции, представляющие интерес для извлечения вложенной строки:

 CHARINDEX

SUBSTRING

LENGTH
  

Вы можете найти в Google подробную информацию о них (например, CHARINDEX по адресу http://msdn.microsoft.com/en-us/library/ms186323.aspx ). С ними вам нужно будет использовать вычисляемые столбцы в вашем запросе, чтобы извлечь это имя местоположения.

Если еще не слишком поздно, вы можете разработать новый способ компоновки этих элементов. Например, вместо:

 locationName1,IpAddress1|locationName2,IpAddress2|etc
  

Как насчет

 {IpAddress1,locationName1}{IpAddress2,locationName2}etc
  

Таким образом, вы можете использовать CHARINDEX для поиска «{» amp; Left(IPAddress, 5); с этой позиции найдите «,»; затем с этой позиции найдите закрывающее «}». Оттуда должно быть просто использовать SUBSTRING для получения LocationName . Имейте в виду, что это, вероятно, будет беспорядочный запрос (вероятно, построенный из нескольких подзапросов, по одному для каждой позиции).

В конце концов, идея SpectralGhost просто читать в столбце и выполнять извлечение в VB, вероятно, является способом с наименьшими трудностями.

Комментарии:

1. Спасибо @rskar, это тоже почти там. Запрос становится очень запутанным, хотя, как вы сказали, и, поскольку я имею дело только с одной записью, я не думаю, что это должно быть настолько сложным.

Ответ №3:

Я решил сделать это таким образом, но был бы признателен за комментарии по эффективности.

Я разделил IPAddress и LocationName на два столбца базы данных, в пределах одной строки, и получаю необходимые данные, сравнивая строки как массивы, согласно приведенному ниже коду.

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

Каждая запись счета-фактуры представляет собой строку в базе данных с аналогичными элементами в счете-фактуре, [item1], [item2] и т.д. Существует еще один столбец для количеств [кол-во1], [кол-во2] и т.д., цен [цена1], [цена2] и т.д. Мне нужно будет иметь возможность искать в базе данных счета-фактуры, в которых встречается номер товара (простой SQL, ГДЕ ItemList, НАПРИМЕР%[invNO]%), а затем сравнивать массивы, чтобы получить количество и индивидуальные цены каждого товара в этом счете. Извлечение этих строк в виде массивов и определение соответствующей позиции в них в соответствии с приведенным ниже кодом будет работать нормально, но когда вся операция проходит через несколько сотен или тысяч строк, станет ли это действительно медленным?

     ipList, locationList = list as comma separated string from database record field

    Dim ipArray As Array = Split(ipList, ",")
    Dim locationArray As Array = Split(locationList, ",")
    For i = 0 To UBound(ipArray)
        If Left(ipArray(i), 5) = Left(ipAddress, 5) Then
            arrayPosition = i
            itemFound = "True"
            Exit For
        End If
    Next
    location = locationArray(arrayPosition)
    'loop through ips then get the position and make the location equal to that
    If itemFound <> "True" Then
        inValidIP = "True"
    End If
  

Комментарии:

1. Поскольку вы спросили об эффективности: описанный выше способ включает чтение двух больших строк из базы данных, а затем создание множества маленьких строк вместе с любыми массивами ссылок, необходимыми для создания экземпляров массивов. За этим следует последовательный поиск, чтобы найти элемент в одном из массивов; что, в свою очередь, требует создания более маленьких строк с помощью вызова Left() . Существует также проблема обеспечения правильного выравнивания элементов массивов IPAddress и LocationName.

2. Для небольшого приложения все это не имеет большого значения, но по мере того, как сервер становится более загруженным, описанный выше подход будет включать в себя большую сборку мусора (начиная со всего создания строки). Также обратите внимание, что вы фактически загружаете всю свою «базу данных» массивов IPAddress и LocationName каждый раз, когда хотите получить доступ к IP-адресам и именам; если для доступа к базе данных требуется доступ к сети, вы подвергаетесь большому избыточному сетевому трафику.

3. Я хочу быть полезным, а не жестоким, но эта идея втиснуть массивы значений в столбцы только ради сохранения всех соответствующих данных в одной строке — это не только наивный подход, но и болезненно неудобный и неэффективный на практике, особенно если вы ожидаете ситуацию «несколько сотен или тысяч строк.»

4. Лучше сделать это правильно в реляционной базе данных. Даже в этой небольшой проблеме «IPAddress и LocationName» было бы намного проще создать другую таблицу для этой цели. Тогда ваш SQL будет выглядеть примерно так: ВЫБЕРИТЕ LocationName ИЗ ApprovedWorkstations, ГДЕ IP-адрес ТИПА «00.00.%».

5. Хм… Я обеспокоен эффективностью. Это конкретное приложение полностью рассматривается в моем примере, и меня это не беспокоит, но когда я пытаюсь извлечь статистику продаж, я хочу, чтобы она была более эффективной. Ни одно из приложений не будет беспокоить многих пользователей, но объем данных будет представлять проблему для последнего приложения. Я просто не могу понять, как структурировать таблицы, чтобы получать статистику продаж, и иметь возможность работать с ними. Мне нужна статистика продаж по каждому продукту с течением времени, и мне нужно иметь возможность удалять продажи, к которым применяются возвраты.

Ответ №4:

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

Но поскольку у вас это есть в одной строке / столбце, почему бы не вернуть это и просто получить значение из .NET?

     Dim Source As String = "TestLocationA,127.0|TestLocationB,128.0|TestLocationC,129.0"
    Dim Test As String = Source
    Dim ToFind As String = "127.0"

    Test = Test.Substring(0, Test.IndexOf(ToFind amp; "|") - 1)
    Test = Test.Substring(Test.LastIndexOf("|")   1)

    MsgBox(Test)
  

или

 Public Class Form1
    Private IpLocationList As New List(Of IpLocation)
    Private IpToFind As String = ""

    Private Class IpLocation
        Public Name As String
        Public IP As String

        Public Sub New(ByVal FullLocation As String)
            Me.Name = FullLocation.Substring(0, FullLocation.IndexOf(","))
            Me.IP = FullLocation.Substring(FullLocation.IndexOf(",")   1)
        End Sub
    End Class

    Private Function FindIP(ByVal IpLocationItem As IpLocation) As Boolean
        If IpLocationItem.IP = IpToFind Then
            Return True
        Else
            Return False
        End If
    End Function

    Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
        Dim Source As String = "TestLocationA,127.0|TestLocationB,128.0|TestLocationC,129.0"
        Dim LocationList As New List(Of String)

        LocationList.AddRange(Split(Source, "|"))

        For Each LocationItem As String In LocationList
            IpLocationList.Add(New IpLocation(LocationItem))
        Next

        IpToFind = "127.0"
        Dim result As IpLocation = IpLocationList.Find(AddressOf FindIP)
        If result IsNot Nothing Then
            MsgBox(result.Name)
        End If
    End Sub
End Class
enter code here
  

Преимущество этого заключается в том, что массив загружается один раз и не требуется вручную перебирать массивы.

Комментарии:

1. Спасибо SpectralGhost … это почти сделало это. Я не могу разделить данные на строки, потому что они должны быть назначены одной записи, это не будет работать с остальными данными, если я это сделаю. Лучший результат, который я могу получить, как показано ниже, который я считал неэффективным.