Using arraylist to insert items into DB - asp.net

I have created an ArrayList with items in my Order.aspx.vb. I pass these on to my bllOrder, which passes it on to my dalOrder.
Order.aspx.vb
Dim item As RepeaterItem
For Each item In rptProductList.Items
objOrder.OrderCustID = Session("CustID")
objOrder.OrderProdID = DirectCast(item.FindControl("ddlProducts"), DropDownList).SelectedValue
bllOrder.InsertOrder(objOrder)
Next item
dalOrder
Function InsertOrder(ByVal objOrder As Order) As Boolean
Dim Result as New Boolean
myconn.open()
Dim SQL As String = "INSERT INTO order(OrderCustID, OrderProdID) VALUES (?,?)"
Dim cmd As New OdbcCommand(SQL, myconn)
cmd.Parameters.AddWithValue("OrderCustID", objOrder.OrderCustID)
cmd.Parameters.AddWithValue("OrderProdID", objorder.OrderProdID)
result = cmd.ExecuteNonQuery()
myconn.close()
Return Result
End Function
This is good for one item, but how would I do it for my ArrayList?
All help is much appreciated!

instead of passing single Order item, pass a List of Orders and them loop it though inside your method. make it like that Public Function InsertOrder(objOrder As List(Of Order)) As Boolean and then use objOrder as a list of Orders to loop it through.
put the following code inside a foreach loop following code and pass the current item values;
cmd.Parameters.AddWithValue("OrderCustID", objOrder.OrderCustID)
cmd.Parameters.AddWithValue("OrderProdID", objorder.OrderProdID)
result = cmd.ExecuteNonQuery()

Convert the array of items into an xml string and you can do a bulk insert in the stored procedure using openxml. http://msdn.microsoft.com/en-us/library/ms191268.aspx also refer an older post for sql server 2005 http://weblogs.asp.net/jgalloway/archive/2007/02/16/passing-lists-to-sql-server-2005-with-xml-parameters.aspx

** edited to account for extra info **
You could adapt the existing "for each" logic in your codebehind to build an arraylist or List<> of products - this array/list should be a property of your Order object. Pass the Order object to the DAL via your BAL as currently.
Then iterate through the products in the Order object in the DAL code(InsertOrder) and either
insert each row individually in a
loop
or dynamically build an insert statement for the Order
.
You should wrap it in a transaction to ensure the order is rolled back competely if one row fails to insert.
For orders with large amout of products i'd go for #Aravind's answer.

I’d use SqlClient.SqlBulkCopy. This is effectively a .Net version of Bulk Insert, to use it you need to either have your objects you want to insert in a either a DataTable or create a class to read your data that implements IDDataReader. If your inserting 1,000’s of rows then you should see a dramatic performace increase and much tidier code.
http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlbulkcopy.aspx

Please go through the following link
How to insert a c# datetime var into SQL Server

I will suggest you to use the comma seperated values . Do not send the array list in your DAL Layer instead a function should return a formatted comma seperated value from the Presentation Layer and send this value to DAL and finally seperate the values in your stored procedure.
Alternative
You can format your values in an XML and send it to Stored Procedure.
In order to perform it your parameter should be of varchar type.

Related

Trying to get a sorted list in vb.net

I have two list boxes (Available Items & Selected Items) which are populated from a database. I'm able to add and remove via buttons between these lists but, when I remove from the Selected list, the item goes to the bottom of the Available list. It does not get alphabetized. So I'm trying a Linq option.
This is the error I'm getting:
Unable to cast object of type 'System.Linq.OrderedEnumerable2[System.Object,System.Object]' to type 'System.Collections.Generic.IEnumerable1[System.Web.UI.WebControls.ListItem]'.
Code:
Imports System.Linq
'After adding the item to the list sort it
Dim myQuery As IEnumerable(Of ListItem)
myQuery = From result In Available.Items _
Select result _
Order By result.Text Ascending
'Rebuild the list
Available.Items.Clear()
For Each item In myQuery
Available.Items.Add(item)
Next
End Sub
Since the ListItemCollection returned by Items only implements IEnumerable, and not IEnumerable(Of ListItem), you should add a Cast to your query. You will also want to use ToList(), or something else that forces evaluation of the query, before you clear it, since LINQ queries are lazily evaluated, and otherwise the list will be cleared before your query is evaluated!
myQuery = (
From result In Available.Items.Cast(Of ListItem)() _
Select result _
Order By result.Text Ascending
).ToList()
You may also want to turn Option Strict On to help find additional
issues at compile time.

Use SQL IN inside vb.net dataset adaptor

I'm trying to use a dataset adapter in my asp.net/vb.net website. But I need to search using multiple values, Ideally, i'd just like to pass an in statement in to my dataset adapter. Is this possible, as how it is, it doesn't seem to bring back anything:
Heres my data adapter:
The query is:
select * from joblist where username in (#username)
I'm trying to call it with:
Private dtJobs As Barry.joblistDataTable
Private taJobs As New BarryTableAdapters.joblistTableAdapter
dtJobs = New Barry.joblistDataTable
dtJobs = taJobs.FilterSearch("'tomb','martinm','chrise'")
rptJobList.DataSource = dtJobs
rptJobList.DataBind()
What am I doing wrong?
You're passing in a comma separated string, a single parameter. You cannot use it as is in an IN statement.
You have to split it into table, for example using this solution. Using this function (I assume you're using SQL Server as your DB) you can rewrite your query as:
select joblist.* from joblist
inner join dbo.Split(',', #username) t
on joblist.username = t.s
This approach splits your multi-value parameter into table and joins to the original table

DataTableMapping using adapter.FillSchema method applied on a Stored Procedure

this is a method i was reading about #MSDN ,
my question is if for an example i would like to use it on a stored procedure
with the fact that the query of that stored procedure is already specifying columns to select from the table like following :
SELECT Columnsome, columnother, , , , ...FROM thisSQLdbTable
though i would like to implement the approach of that specific method , it seems very advanced from a little research i have made on
"the best way" available to extract data from SQL Server into Asp.net DataTable.
public static DataTable GetCustomerData(string dataSetName,
string connectionString)
{
DataTable table = new DataTable(dataSetName);
using (SqlConnection connection = new SqlConnection(connectionString))
{
SqlDataAdapter adapter = new SqlDataAdapter(
"SELECT CustomerID, CompanyName, ContactName FROM dbo.Customers", connection);
DataTableMapping mapping = adapter.TableMappings.Add("Table", "Customers");
mapping.ColumnMappings.Add("CompanyName", "Name");
mapping.ColumnMappings.Add("ContactName", "Contact");
connection.Open();
adapter.FillSchema(table, SchemaType.Mapped);
adapter.Fill(table);
return table;
}
}
or is it not the method to use if i am querying via SP that specifies the selected column
i could actually drop that stored procedure if it is not requiered to select /specify columns
the stored procedure is doing a specific calculation and updates the table with results of calculation then i am switching it's "MODE" to select results from the table that was updated.
what i did is recyceling (; giving it a parameter (bit type)
stored procedure then asks for the value of supplied bool / bit Parameter,
if its is status true it updates (doing its original task it was made for)
if its false its doing a select oporation so i am using it as i would with 2 separated commands
but now that i have search for a better way to extract data from db into a Data table
i give up on the two way SP and i will make a selection via the exaple above if they're not intended to be used thogether as with my current SP that does preselection when servs the GetCustomersData() above.
So the question is do i need to let the function to make the selection or can i serve it with my sp ready made selection to implemet it with GetCustomersData() in the way that it will only do rest of task and only mapp the columns that was preselected
Still a bit confused on your actual requirement but here goes:
I See you are using a direct query in your C# code, 'best way' would be to make a SP out of it then say:
SqlCommand command = conn.CreateCommand();
SqlDataAdapter sqlAdapter = new SqlDataAdapter(command);
command.CommandType = System.Data.CommandType.StoredProcedure;
command.CommandText = "sp_GetCustomerData";
Then after you have added parameters if needed do:
conn.Open();
sqlAdapter.Fill(dtResult);
conn.Close();
Where dtResult is Datatable.
So you do not need to do any mapping in this case, and since you are using a SP from the Database it will work faster than your direct query and you can change the query logic any time without the need of re deploying your code.
Stored procedures are perfectly valid in this use case. however, if you want more of a properly mapped table, you have several options, some of which go beyond the use of DataTables.
You can use strongly typed DataSets or perhaps use an ORM (object relational mapper).
ref: Typed Datasets: http://msdn.microsoft.com/en-us/library/esbykkzb(v=vs.71).aspx
ref: What is an ORM : http://en.wikipedia.org/wiki/Object-relational_mapping
EXAMPLES OF ORM'S
ref: Entity Framework : http://msdn.microsoft.com/en-us/data/ef.aspx
ref: NHibernate: http://nhforge.org/

how to query strongly type datatable

I have a news portal.
For this portal I have a database with a "News" table and with the following columns
(NewsID, CategoryID, NewsTitle, NewsText, DateAdded, ImagePath, TotalRead, NewsType, isActive)
I use dataset files (.xsd) and for this one, I have a query that returns the last 3 days' news into a custom class that I coded, named HHNews.
HHNews Class has a function that returns a strongly-typed datatable that includes the results of the query I mention above.
The home page has different sections for news.. these are;
- Headlines (5 items)
- Sub-headings (4 items)
- Last 5 news items for each of the news categories...( categories are like; sports, local news, economics,
For the home page, I retrieve the datatable returned from the class. Now I want to query this datatable and build the sections I mention above.. e.g.
if my datatable is called "dt", then is there a way to sql-like query this dt such as "select TOP(5) NewsID, NewsTitle, NewsText from dt where NewsType = 0" -- 0 representing the headline ?
Absolutely. You can use LINQ as Dave Cluderay mentioned. To retrieve your headlines, for example, you could run:
var myDataTable = dt.AsEnumerable();
var headlines = myDataTable.Where(t => t.NewsID == 0).Take(5);
You can use LINQ to DataSet if you're in .NET 3.5.
If you aren't in .NET 3.5, you can create a DataView based on the DataTable object and then set the RowFilter property on the DataView. For example:
DataView myDV = new DataView(dt);
myDV.RowFilter = "NewsType = 0";
You can then catch only the first 5 rows in your DataView.
You can use the default view to filter the datatable like so:
dt.DefaultView.RowFilter = "NewsType = 0";
Not sure how you would get the top 5!?
If you're not in 3.5 you could use a simple for loop to get the top 5 rows after sorting the table.
There is a Select method on the Datatable, dont think there is a way to limit the amount returned. I like the LINQ way, but just an alternative....but the limit might count this out.
dt.Select("NewsType = 0");

order by not working

I am using an objectdatasource with a gridview to get data from my orm class, but I cannot get it to order by properly.
I am using the code below but it does not come up in descending order like I have specified below. What am I missing? Using subsonic 2.1
<DataObjectMethod(DataObjectMethodType.Select, True)> Public Function FetchByPatID(ByVal PatientID As Object) As VisitCollection
Dim coll As VisitCollection = New VisitCollection().Where("PatientID", PatientID).Load()
**OrderBy.Desc(Visit.DosColumn)**
Return coll
End Function
The order by is executed against the database as part of your query. It needs to be added before the .Load() method is called.
Dim coll As VisitCollection = New VisitCollection().Where("PatientID", PatientID).OrderByDesc(Visit.Columns.DosColumn).Load()
Ranomore is correct. You must specify the OrderBy before you actually execute the command as the ordering is done on the database.
If you are using SubSonic 2.1 I much prefer the new syntax that has been added which makes the Query much more readable
SubSonic.Select.AllColumnsFrom(Of Visit)().Where(Visit.PatientIDColumn).isEqualTo(PatientID).OrderByDesc(Visit.DosColumn.ColumnName).ExecuteAsCollection(Of VisitCollection)()

Resources