Hello everone
I have a function
public void RemoveStock(string tickerName) {
int key = this.getKeyFromtickerName(tickerName);
foreach (var item in listingDataTable.Where(
x => x.stock == key).ToList()) {
listingDataTable.RemoveListingRow(item);
}
listingTa.Update(listingDataTable);
}
Definitions:
listingDataTable = new stockDataSet.ListingDataTable();
listingTa = new stockDataSetTableAdapters.ListingTableAdapter();
Database type: SQL Server Compact Edition
The function remove rows from the dataset, but not from the database. All additions to the database is stored but I can't delete from the database.
Do I need to do something else to make the database to accept my changes?
Best Regards
Gorgen
Try this instead:
foreach (var item in listingDataTable.Where(
x => x.stock == key).ToList()) {
item.Delete();
}
I think this will actually mark the row for deletion.
Turned out that I needed to add an DeleteCommand in my database adapter. The DeleteCommand wasn't automaticly generated and when using .RemoveListingRow(item) no error message was issued, it just didn't work.
In Data Sources choose "Edit DataSet with Designer" Properties of tableAdaper generate command such as
DELETE FROM Listing
WHERE (stock = #p1)
Related
I have a ObservableCollection<Admissiontb> and i want to add this list to Sql Table.
The following code only add last record! Seeking any help and thanks in advance.
private void AddrecordToSql(object obj)
{
AdmissiondbEntities db = new AdmissiondbEntities();
foreach (var item in admissiontbsColl)
{
db.Admissiontbs.Add(item);
}
db.SaveChanges();
MessageBox.Show("Done");
}
Trying to add records from the collection to the SQL table
You could try using addrange instead.
You need to call .ToList() on your observablecollection which is in the system.linq namespace ( using ).
Then you can do something like is explained here:
https://www.tektutorialshub.com/entity-framework-core/add-record-add-multiple-records-in-entity-framework/
AdmissiondbEntities db = new AdmissiondbEntities();
var addList = admissiontbsColl.ToList();
db.Admissiontbs.AddRange(addList);
db.SaveChanges();
MessageBox.Show("Done");
I have function which inserts record in database. I want to make sure that there are no duplicate entries in database. Function first checks if there is query string parameter. If there is, then it acts like edit mode otherwise insert mode. There is a function which can return currently added records in database. I need to check duplication based on two columns before insertion in database.
myService = new myService();
myFlow mf = new myFlow();
if (!string.IsNullOrEmpty(Request["myflowid"]))
{
mf = myService.Getmyflow(Convert.ToInt32(Request["myflowid"]));
}
int workcount = 0;
int.TryParse(txtWorkCount.Text, out workcount);
mf.Name = txtName.Text.Trim();
mf.Description = txtDescription.Text.Trim();
mf.FunctionCode = txtFunctioneCode.Text.Trim();
mf.FunctionType = txtFunctioneType.Text.Trim();
mf.WorkCount = workcount;
if (mf.WorkFlowId == 0)
{
mf.SortOrder = 0;
mf.Active = true;
mf.RecordDateTime = DateTime.Now;
message = "Saved Successfully";
}
else
{
_editMode = true;
message = "Update Successfully";
}
}
int myflowId = mfService.AddEditmyflow(mf);
I want to check duplication based on functiontype and functioncode. Another function mfService.Getmyflows() can return currently added records in database.
How can I check duplication using Linq?
First of all, what database do you use? Many databases support upsert behavior (update or insert depending of was data found or not). For example, MERGE in ms sql, MERGE in oracle, INSERT .. ON DUPLICATE in mysql and so on. This could be preferred solution. Upsert is usually an atomic operation.
In your particular case do you you transactions? Are you sure no one will insert data after you ensured about duplicates but before you have inserted your record? Example:
#1 thread #2 thread
look for duplicates
... look for duplicate
no duplicates found ...
no duplicates found
insert data_1
insert data_1
This will end up with duplicates you trying to avoid.
According to your code you populating data from GUI and adding only one item.
If you have access to myService code you could add method to query item by your two columns, instead of querying all items via mfService.Getmyflows() and looking through this collection inside your code. It would be more performant (especially if you have indexes in that columns) and more memory efficient.
And finally, existing of a single element inside collection can be easily done:
var alreadyExist = mfService.Getmyflows()
.Any(x => x.Column1 == value1 && x.Column2 == value2);
Using Entity Framework,I need to Retreive A List Of Entities Then Manipulate This List Based On Some Conitions, then Save The Final List to Context.
Like This:
Sample
{
int id;
int value;
}
var sampleList=db.samples.toList();
//Add some records to sampleList
sampleList.Add(new sample(){value = 10});
//Change the Value of Some Records in sampleList
sampleList[0].value= 5 ;
db.savechanges()
Added Records to List Are not Tracked And Inserted To DB ,But Changed Values Are Updated.
Strange Behavior Of EF!! Any Explanation???
Thanks!
Hmm, base on your script, what should've been done is something like this.
//var sampleList=db.samples.toList();
//Add some records to sampleList
Sample sampInsertObject = new sample() { value = 10 };
db.samples.Add(sampInsertObject);
db.SaveChanges(); // execute save so that context will execute "INSERT"
/*
EF also executes SCOPE_IDENTITY() after insert to retrieve the
PrimaryKey value from the database to sampInsertObject.
*/
// Change the Value of Some Records in sampleList
var sampUpdateList = db.samples.ToList();
if(sampUpdateList.Count != 0)
{
// Get specific object from sample list
Sample sampUpdateObject = sampUpdateList.ToList()[0];
sampUpdateObject.Value = 5;
db.SaveChanges(); // execute save so that context will execute "UPDATE"
}
Let me first answer the easier question of why your new records were not saved. You cannot just modify the objects and call save changes, you need to either Add or Update the DataBase.
db.Add(sample); // If sample does not exist
db.Update(sample); //If sample already exists and you are updating it
db.SaveChanges();
As for modifying the list and saving that to context. I believe you will have to iterate over the list itself and Add, Delete, Update each Sample Object in it.
I am currently trying to create a new order (which will be shown below) in a web service, and then send that data to insert a new row into the database. For some reason my DBML / Data Context does not allow me to use InsertOnSubmit.
Any ideas? I haven't used Linq to Sql in about 7 months.
Thanks in advance.
[WebMethod]
public string InsertOrderToDatabases()
{
//Start Data Contexts ------
DataContext db = new DataContext(System.Configuration.ConfigurationManager.AppSettings["RainbowCMSConnectionString"]);
DataContext dcSqlOES = new DataContext(System.Configuration.ConfigurationManager.AppSettings["OESConnectionString"]);
//Get table from local database
Table<Schedule> Schedule = db.GetTable<Schedule>();
//Find last order number in databases
var lastOrderNumber = from lOrder in Schedule
orderby lOrder.templ_idn descending
select lOrder.templ_idn;
int firstOrderID;
var firstOrder = lastOrderNumber.FirstOrDefault();
firstOrderID = firstOrder.Value + 1;
qrOrder qrOrd = new qrOrder
{
.... data in here creating a new order
};
//TODO: fix below with an insert on submit
if (qrOrd != null)
{
// **Schedule.InsertOnSubmit(qrOrd);**
}
//db.GetTable<Schedule>().InsertOnSubmit(qrOrd);
try
{
//Submit the changes to the database
db.SubmitChanges();
return "Orders were sent to the databases.";
}
catch ()
{
}
}
Based on your response, it appears that you are using the wrong table, or perhaps the wrong data type. I also noticed that when you declare your localSchedule variable, you declare it as type Table<Schedule>, which means it should contain Schedule entities, not qrOrder entities.
Table<TEntity>.InsertOnSubmit expects a specific strongly typed entity to be passed in. In your case, it is expecting Web_Service.Schedul‌e, but you are trying to pass in a qrOrder.
Schedule.InsertOnSubmit(qrOrd);
That line will not treat to submit changes to connected entity , Try this
db.Schedule.InsertOnSubmit(qrOrd);
db.SubmitChanges();
you can try with
db.GetTable(typeof(Schedule)).InsertOnSubmit(qrOrd);
Or
db.GetTable(qrOrd.GetType()).InsertOnSubmit(qrOrd);
Using the query function of entity collection in C# and it takes a long time to load the related records back from SQL Server 2008. Is there any fast way to do this? This is the query function I use:
public void SearchProducts()
{
//Filter by search string array(searchArray)
List<string> prodId = new List<string>();
foreach (string src in searchArray)
{
StoreProductCollection prod = new StoreProductCollection();
prod.Query.Where(prod.Query.StptName.ToLower() == src.ToLower() && prod.Query.StptDeleted.IsNull());
prod.Query.Select(prod.Query.StptName, prod.Query.StptPrice, prod.Query.StptImage, prod.Query.StptStoreProductID);
// prod.Query.es.Top = 4;
prod.Query.Load();
if (prod.Count > 0)
{
foreach (StoreProduct stpt in prod)
{
if (!prodId.Contains(stpt.StptStoreProductID.ToString().Trim()))
{
prodId.Add(stpt.StptStoreProductID.ToString().Trim());
productObjectsList.Add(stpt);
}
}
}
}
You're hitting the database once per searchArray item, this is very wrong.
You might get better performance like this (have no way of testing it, give it a shot):
public void SearchProducts()
{
//Filter by search string array(searchArray)
List<string> prodId = new List<string>();
StoreProductCollection prod = new StoreProductCollection();
// Notice that your foreach() is gone
// replace this
// prod.Query.Where(prod.Query.StptName.ToLower() == src.ToLower() && prod.Query.StptDeleted.IsNull());
// with this (or something similar: point is, you should call .Load() exactly once)
prod.Query.where(prod.Query.StptDeleted.IsNull() && src.Any(srcArrayString => prod.Query.StptName.ToLower()==srcArrayString.ToLower());
prod.Query.Select(prod.Query.StptName, prod.Query.StptPrice, prod.Query.StptImage, prod.Query.StptStoreProductID);
// prod.Query.es.Top = 4;
prod.Query.Load();
// ... rest of your code follows.
}
Given List<string> searchArray containing lowered words :
public void SearchProducts()
{
//Filter by search string array(searchArray)
List<string> prodId = new List<string>();
StoreProductCollection prod = new StoreProductCollection();
prod.Query.Where(searchArray.Contains(prod.Query.StptName.ToLower()) && prod.Query.StptDeleted.IsNull());
prod.Query.Select(prod.Query.StptName, prod.Query.StptPrice, prod.Query.StptImage, prod.Query.StptStoreProductID);
// prod.Query.es.Top = 4;
prod.Query.Load();
if (prod.Count > 0)
{
foreach (StoreProduct stpt in prod)
{
if (!prodId.Contains(stpt.StptStoreProductID.ToString().Trim()))
{
prodId.Add(stpt.StptStoreProductID.ToString().Trim());
productObjectsList.Add(stpt);
}
}
}
}
This way you have only one query for all words.
First of all, put an index on StptName column.
Second, if you need even better performance, write a Stored Procedure in SQL, to do your querying, and map it with Entity Framework.
Let me know if you need explanation on how to do any of the above.
A couple more micro-optimizations you can do if you don't want to write a Stored Procedure:
Write src.ToLower() in a temporary varaible, and than compare prod.Query.StptName.ToLower() to it.
By default, SQL Server queries are case insensitive, so check if that's the case, and if so, you can get rid of the ToLower altogether. You can change case sensitivity through Collation.
EDIT:
To create an Index:
Open the table designer in SQL Server Managment Studio.
Right click anywhere and select Indexes/Keys.
Click Add.
Under Columns add StptName.
Under Is Unique specify whether StptName is unique or not.
Under type select "index".
That's all!
As for mapping stored procedures - here's a nice tutorial:
http://www.robbagby.com/entity-framework/entity-framework-modeling-select-stored-procedures/
(You can jump straight to the "Map in the Select Stored Procedure" Section).