#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 … это почти сделало это. Я не могу разделить данные на строки, потому что они должны быть назначены одной записи, это не будет работать с остальными данными, если я это сделаю. Лучший результат, который я могу получить, как показано ниже, который я считал неэффективным.