Am currently looking to use this code to display vehicle information in a data grid view in visual studio 2022 using c# :-
connStr = #"Data Source = .\sqlexpress; Initial Catalog = TDsSalesnService; Integrated Security = true";
// Setting up data adapter for datagridview display
sqlVehicleDetails = #"SELECT M.MakeName AS Make, ML.ModelName AS Model, V.Registration AS Reg, V.VINNum, V.PriceCost, V.PriceSell, V.Colour, VT.VehicleTypeDesc AS Type, V.Transmission, V.EngineSize, V.FuelType, V.Mileage, V.Condition, V.VehicleYear AS Year, V.Availableness AS Availability
FROM Vehicle V
JOIN VehicleType VT ON V.VehicleTypeID = VT.VehicleTypeID
JOIN Model ML on V.ModelID = ML.ModelID
JOIN Make M on ML.MakeID = M.MakeID
ORDER BY M.MakeName, ML.ModelName, VT.VehicleTypeDesc, V.VehicleYear ASC";
conn = new SqlConnection(connStr);
cmdVehicleDetails = new SqlCommand(sqlVehicleDetails, conn);
daVehicleDetails = new SqlDataAdapter(sqlVehicleDetails, conn);
cmdBVehicleDetails = new SqlCommandBuilder(daVehicleDetails);
daVehicleDetails.FillSchema(dsTDsSalesnService, SchemaType.Source, "Vehicle");
daVehicleDetails.Fill(dsTDsSalesnService, "Vehicle");
This works fine.
The issue comes when I go to write records to the database and it's saying it doesn't accept null values for the first field m.makename.
I was hoping to use and call the vehicle table using this code so i can write new records in the correct format :-
sqlVehicle = #"SELECT * from Vehicle";
daVehicle = new SqlDataAdapter(sqlVehicle, connStr);
cmdBVehicle = new SqlCommandBuilder(daVehicle);
daVehicle.FillSchema(dsTDsSalesnService, SchemaType.Source, "Vehicle");
daVehicle.Fill(dsTDsSalesnService, "Vehicle");
But keeps throwing error about the tables used not being unique.
I truth I would need each line explained as to what is going on so i can map in my head how the process is functioning as I don't think an just understanding it tbh.
Any help would be appreciated.
So the error reads System.ArgumentException:
'These columns don't currently have unique values.'
and it points to the daVehicle.FillSchema(dsTDsSalesnService, SchemaType.Source, "Vehicle"); line.
What am basically trying to do is have the datadgrid view display the vehicle details formatted using the first block of code to make it more legible to the user, but when I go to add records to the database I want to use it's raw format using the second block of code without utilizing the extra naming conventions and there's a extra field there that cause additional problems writing to the db even if i don't use the 2nd block of code.
I can use the second block of code as it for display and writing to the db but it's now useful to the user, looks awful and very hard to reads as it's codes in place of the fields instead of proper names.
datagridview using 1st block of code only
datagridview using 2nd block of code only
Related
EDIT: Thank you everyone, I figured out how to get it to work now! Details below...
I'm kind of a newbie to C#, and I'm trying to teach myself the language by programming a really simple RPG game.
Right now, I'm at the point where I want to start adding different enemies to fight (up until now I just used a single one hardcoded in for testing).
I've started setting up a database with enemy info (one column for name, one for HP, one for common stats and attacks, etc.). I have it so that when you start combat with an enemy, the player is able to select a creature from a dropdown, and whichever creature he has will set a variable called "EnemyID".
What I want to do is use that EnemyID variable to correspond to a row in my database, then pull the value of each column into variables that I can then reference during combat.
Is this something that's possible to do? If so, could someone explain the method to me in relatively simple terms? Even just a small example of how to import row data from any kind of database will do, I'm good at understanding code once I see it in use a couple of times.
(Oh yeah, if it matters, I'm using Visual Studio Express 2013, and my database is a SQL Server Express 2014 database.)
Thanks in advance!
EDIT:
After finding a simple tutorial for ADO.NET, and following a suggestion from one of the posters, I've come up with the following code.
public void DataPoll()
{
SqlConnection MonDat = new SqlConnection("Data Source=(local);
Initial Catalog=TestDatabase;Integrated Security=SSPI");
SqlDataReader rdr = null;
try
{
MonDat.Open();
SqlCommand cmd = new SqlCommand(
"select * from Monsters where Id = EnemyID", MonDat);
rdr = cmd.ExecuteReader();
while (rdr.Read())
{
EnemyIDBuffer = (int)rdr["Id"];
EnemyName = (string)rdr["Name"];
EnemyHPBase = (int)rdr["HP"];
EnemyAtkBase = (int)rdr["Atk"];
EnemyDefBase = (int)rdr["Def"];
EnemyMagBase = (int)rdr["Mag"];
PrimAtk = (string)rdr["PrimAtk"];
SecoAtk = (string)rdr["SecoAtk"];
TertAtk = (string)rdr["TertAtk"];
RareAtk = (string)rdr["RareAtk"];
}
}
finally
{
if (rdr != null)
{
rdr.Close();
}
if (MonDat != null)
{
MonDat.Close();
}
}
}
However, when I try to run it, my program stalls and crashes. I'm guessing I have something configured wrong (I just took script from the tutorial and tweaked it slightly). Can anyone give me a hand figuring out where I went wrong?
EnemyID is a variable I used to assign what enemy is fought, based on a menu selection. I'm trying to use that variable to generate the row ID to pull the rest of the row data from, but I think that might be causing an issue.
EDIT2: It took me longer than it really should have, but I figured it out. I had to change my code a little tiny bit.
SqlCommand cmd = new SqlCommand(
"select * from Monsters where Id = " + EnemyID, MonDat);
I have a habit of forgetting that you're able to join statements like this. I made a new project that only polled data and threw it into my variables, and from there put it into text boxes, and with this method I was able to poll two different sets of enemy stats by assigning different EnemyID values to two different buttons. Proof of concept, right there.
Thanks to both people who replied, both suggestions were equally useful to getting this working. :)
There's numerous tutorials out there on how to use a database, the first two use straight ADO.NET which is pure data access, making you responsible for its interaction in your code:
ADO.NET Overview
ADO.NET Tutorial for Beginners
The next two, one is for Entity, and the other for nHibernate, they connect to SQL databases and convert the objects there to usable code in your program through a process called object relational mapping.
Entity Framework Tutorials
nHibernate Tutorials
These are all relevant links to stuff in the most current years, with VS 2013; hopefully that provides you a good starting point.
You can do something like this:
Your SQL should pass in the procedure name and EnemyId.
The stored procedure would do a select * from Enemies where EnemyId = #EnemyId
DataSet dataSet = HSPDataAccessProxy.Instance.ExecuteDataSet(sql);
The dataSet has the table that is returned by the store procedure and you can retrieve the columns you need from that table.
I'm kind of new to C# and am trying out the convenient looking adaper-dataset combo with local database. while I was amazed at how easy and useful it was I stumbled upon an issue:
Whenever I try to fill the Item table with the adapter I get Invalid object name SQLexception,
I use the same Dataset for all my tables, dsOns.Users / dsOns.Items.
The problem is, the users adapter does recognize and successfully works with Users database(dbo.Users) while the items adapter cannot find the table(dbo.Item).
Heres some sniplets:
UsersTableAdapter uAdapter = new UsersTableAdapter();
ItemTableAdapter iAdapter = new ItemTableAdapter();
Users select:
SELECT Id, name, password, sold, isLogged, lastLog FROM dbo.Users
Item select:
SELECT Id, name, sale_price, min_price, cog FROM dbo.Item
Both use the same connection string:
Data Source=(LocalDB)\v11.0;AttachDbFilename=|DataDirectory|\ons_data.mdf;Integrated Security=True;Connect Timeout=30
Also note that in Dataset designer, the adapter works fine, it selects successfully. The error only occurs in code.
Image of the schema:
What could possibly cause this?
Okay that was weird, I solved it by simply changing the view of the database explorer, to find that the app uses two databases, in UI(dataset designer) it uses my original db, while in code it uses the same db(but outdated since I changed it via dataset designer) that was copied to debug folder, hence containing only Users table alone and resulting in the error
I am unsure if item may be considered a reserved word in some cases perhaps in the context of your connection. Might want to refer to is at [dbo].[item].
Try changing the query which you are passing to the SqlDataReader in my case it was "Select [Name],[Location],[Email] FROM [dbo].[CreateDB]" but I tried "Select Name,Location,Email FROM YourTableName" and it worked, you can also use "Select * FROM YourTableName".
need to know the exact info of database and containing tables using c#.
database is MS access.i want to full info of the tables in it like primary key,max length,not null of the columns in tables in ms access database,etc..
so whats the best way of doing it....
advanced thanx for any kind of help.
another issue is getschema gives me datatypes in numeric way like 130,131..
so how can i use them in create table query they give error
let me explain what i am trying to do.i want to recreate the database about which i have no information.i don't know about its size,tables,data or any thing.
actually i have succeeded to an extent.what i have done is i get the db name and create it with CatalogClass and with getschema(tables) i get all the table names and create them with create table from C#.then column names with alter table.and now i have to give it constraints which are in the DB which have been provided.
so,other then this method i have used is there any thing else which i am missing.any easy or better way available to do this.so, it can go faster
question is still open
I believe everything is documented at the link below, try to run it step by step with debug and then u can inspect the element and display every value you want.
http://msdn.microsoft.com/en-us/library/system.data.datatable.aspx
Primary Key:
DataTable.PrimaryKey
Max Length, of what? Records?
DataTable.Rows.Count
Columns?
DataTable.Columns.Rows
It appears that you are using a schema to return the field types. I have been testing, and something on these lines appears to return what you want.
ADODB.Connection cn = new ADODB.Connection();
ADODB.Recordset rs = new ADODB.Recordset();
string cnStr;
cnStr = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=Z:\\Docs\\Test.accdb";
string ssql = "Select * From Table1 where 1=2";
cn.Open(cnStr, null, null, 0);
rs.Open(ssql, cn, ADODB.CursorTypeEnum.adOpenKeyset,
ADODB.LockTypeEnum.adLockOptimistic, -1);
foreach (ADODB.Field fld in rs.Fields)
{
Console.WriteLine(fld.Type);
}
Console.Read();
rs.Close();
cn.Close();
For various types this returns:
adInteger
adVarWChar = Text
adDate
adInteger
adLongVarWChar = Memo
adVarWChar
adDate
adBoolean
I've a WPF situation with one page that has a datagrid with clients, and another page with field to fill in a new client.
I want the "new-client-page" to search the highest clientID en increment that with 1 for the new client, this sounds very simple, but I've a problem with it.
In the table adapter of the table, I added a new query: SELECT MAX(clientID) FROM clients
I execute the query with:
DataSet1TableAdapters.klantenTableAdapter tableAdapter = new DataSet1TableAdapters.klantenTableAdapter();
DataSet1 datasetvar = new DataSet1();
int returnValue = (int)tableAdapter.GetMaxKlantnr();
This works fine once. I get the highest value in returnValue, but if I go for the second time to the "new-client-page", the clientID is still the same..
I tried to update the dataset with tableAdapter.Update(datasetvar); but that doesnt make sense.. :(
Lars what database are you using? Set the ID column as identity and it will be auto generated by the db, your solution would not support any concurrency anyway and it's not the way to go to read the max id and add 1 to it...
You need to set it when you add a new row. It is then executed as an INSERT by the adapter. Adapters commit only changes.
The code would look almost like:
var newRow = ClientTable.NewRow();
newRow["ClientID"] = GetNewID();
...set other fields...
ClientTable.Rows.Add(newRow);
Adapter.Update(ClientTable);
I'm new to C# and .NET in general, coming from a FLOSS background (mostly PHP, Python and Ruby). I have used the Data Source configuration wizard to connect to an MDB file (unfortunately need to do this, as the app this is being used with was written over 5 years ago, and is currently a VB6 app connecting to an Access database). The wizard created a DataSet class JobDataSet with the following DataTables in it (among others):ItemType, Item. ItemRevision
In the MDB, these map to the following tables:
ItemRevisions (
ID: AutoNumber PK,
JobNo: Text,
ItemTypeID: Number,
ItemNo: Number,
RevisedAt: Date/Time,
RevisedBy: Text,
ItemID: Number
)
Items (
ID: AutoNumber PK,
JobNo: Text,
ItemTypeID: Number,
ItemNo: Number
)
ItemTypes: (
ID: AutoNumber PK,
Type: Text
)
Anyway, the following is the code for the method that doesn't work:
private void AddJobItem()
{
itemTypesBindingSource.EndEdit();
JobDataSet.ItemsRow itemsRow = jobDataSet.Items.NewItemsRow();
itemsRow.ItemTypeID = long.Parse(comboBoxItemType.SelectedValue.ToString());
itemsRow.JobNo = JobNo;
itemsRow.ItemNo = (long)numericUpDownItemNo.Value;
jobDataSet.Items.Rows.Add(itemsRow);
jobDataSet.Items.AcceptChanges();
itemsTableAdapter.Update(jobDataSet.Items);
JobDataSet.ItemRevisionsRow itemRevisionsRow = jobDataSet.ItemRevisions.NewItemRevisionsRow();
itemRevisionsRow.ItemTypeID = long.Parse(comboBoxItemType.SelectedValue.ToString());
itemRevisionsRow.JobNo = JobNo;
itemRevisionsRow.ItemNo = (int)numericUpDownItemNo.Value;
itemRevisionsRow.RevisedAt = System.DateTime.Now;
itemRevisionsRow.RevisedBy = Program.AuthForm.Username;
itemRevisionsRow.ItemID = itemsRow.ID;
jobDataSet.ItemRevisions.Rows.Add(itemRevisionsRow);
jobDataSet.ItemRevisions.AcceptChanges();
itemRevisionsTableAdapter.Update(jobDataSet.ItemRevisions);
jobDataSet.AcceptChanges();
}
Basically, the issue is, everything gets set properly as far as the object properties are concerned (checked this by single stepping through the debugger and looking at the values of the objects in question), no exceptions are being thrown. But the primary keys stay -1 instead of setting to an actual database ID, and the data is never actually added to the tables. I'm sure I'm missing something simple here (like I said, new to this, first ADO.NET disconnected layer app), so if anybody could help it would be appreciated.
BY calling AcceptChanges before using the adapter, you are basically saying that all data in the dataset is unmodified and current. The adapter will hence do nothing. Do not call AcceptChanges before running it through the DB, only when the DB operation succeeds it makes sense to "AcceptChanges"