C# Entity Framework and stored procedures - c#

I made my database with its stored procedures then attached it with my project Entity Framework database-first.
This function to insert a company info and return its id back and insert it to another table in relation with company table
public string InsertCompany(company company, out int index)
{
try
{
using (vendors_managerEntities db = new vendors_managerEntities())
{
db.companies.Add(company);
db.SaveChanges();
index = company.id_company;
return $"{company.name_company} Is Saved";
}
}
catch (Exception ex)
{
index = 0;
return ex.Message;
}
}
But when I tried to my stored procedure which has been created in database, I couldn't return any value the id always be 0
public string InsertCompany(company company, out int index)
{
try
{
using (vendors_managerEntities db = new vendors_managerEntities())
{
db.SP_insert_companies(company.name_company, company.website_company, company.adress_company, company.county_company, company.decription_company);
index = company.id_company;
return $"{company.name_company} Is Saved";
}
}
catch (Exception ex)
{
index = 0;
return ex.Message;
}
}
I read that I can make it in SQL but I'm looking for a solution in C#, so I opened the stored procedure definition in C# and found the following code and was thinking if can I change its return value because it's not return the id value
public virtual int SP_insert_companies(string name, string website, string address, string country, string description)
{
var nameParameter = name != null ?
new ObjectParameter("name", name) :
new ObjectParameter("name", typeof(string));
var websiteParameter = website != null ?
new ObjectParameter("website", website) :
new ObjectParameter("website", typeof(string));
var addressParameter = address != null ?
new ObjectParameter("address", address) :
new ObjectParameter("address", typeof(string));
var countryParameter = country != null ?
new ObjectParameter("country", country) :
new ObjectParameter("country", typeof(string));
var descriptionParameter = description != null ?
new ObjectParameter("description", description) :
new ObjectParameter("description", typeof(string));
return ((IObjectContextAdapter)this).ObjectContext.ExecuteFunction("SP_insert_companies", nameParameter, websiteParameter, addressParameter, countryParameter, descriptionParameter);
}
Please tell me if there's a solution in C# or should I go back to old code without stored procedure in that case?

The issue is that you are using a stored procedure to insert the company entity which I suspect does not cause the object to be refreshed by the context:
db.SP_insert_companies(company.name_company, company.website_company, company.adress_company, company.county_company, company.decription_company);
You then try to get the id from the object which is 0 because it hasn't been refreshed:
index = company.id_company;
If you insist on using a stored procedure, what I would suggest is that you have the SP return the id of the company, then grab it from the call and use that as the value of index:
index = db.SP_insert_companies(company.name_company, company.website_company, company.adress_company, company.county_company, company.decription_company);
Once you modify the SP, make sure to update the definition in your code so it knows to make a function that returns a value.
If you prefer to have it in the object itself, then make sure to update it manually, although I don't recommend this as the object is not in true sync with the database:
index = db.SP_insert_companies(company.name_company, company.website_company, company.adress_company, company.county_company, company.decription_company);
company.id_company = index;

Based on what you're saying it's automatically going to the "Catch" and then the index is already set to 0. So chances are your code elsewhere, not listed is messing up. I suspect wherever your code for saving the company information isn't saving properly. Try manually inputting a company into the DB and then check it with your program. If it returns that it's "Saved" then you know your problem isn't within this method and is a result of your saving method.

Related

SaveChanges problem in N-Tier Architecture

Normally, with MVC I use db.savechanges() method after I do some processes. But check the below code when I use N-Tier Architecture in everyloop its gonna insert in this way but I dont want it. I have to check all the items first. If there is no problem then I have to insert it all together.
foreach (var item in mOrderList)
{
MOrder mOrder = new MOrder();
mOrder.StatusAdmin = false;
mOrder.Date = DateTime.Now;
mOrder.StatusMVendor = "Sipariş alındı.";
mOrder.HowMany = item.HowMany;
mOrder.MBasketId = item.MBasketId;
mOrder.MProductId = item.MProductId;
mOrder.MVendorId = item.MVendorId;
mOrder.WInvestorId = item.WInvestorId;
MProduct mprostock = _imProductService.GetMProductById(item.MProductId);
if (mprostock.Stock<=0)
{
return ReturnErrorAndSuccess(HttpStatusCode.NotFound, "MProduct", mprostock.Name + " ürününde stok kalmadığı için işlem tamamlanamadı.");
}
_imOrderService.InsertMOrder(mOrder);
}
all you have to do is:
first you should define a method that get list of mProductId and then return list of MProduct.
after that you should check if there is any record with Stock<=0 then return your error.
-also for your insert you should define a method that get list of MOrder and return appropriate datatype for example Boolean.
public List<MProduct> GetMProductByIds(List<MProductId> mProductId)
{
//getting record code
}
public bool AddMOrder(List<MOrder> mOrder)
{
//inserting record code
}

Xamarin.iOS/How to retrieve a record from CloudKit by using only the Key

I was reading the Xamarin iOS documentation about CloudKit but it seems is not clear enough how to get the values of a specific record.
In the code below is what the documentation says how to fetch a record by using the "RecordID" but the recordID is generated on the cloudKit so I can't know the ID.
`
// Create a record ID and fetch the record from the database
var recordID = new CKRecordID("MyRecordName");
ThisApp.PublicDatabase.FetchRecord(recordID, (record, err) => {
// Was there an error?
if (err != null) {
...
}
});
`
I tried to use a Query to fetch a record by using the "Key" and the "Value" as the documentation suggest like this
NSPredicate.FromFormat(string.Format("{0} = '{1}'", key, value)), which it works only because I know both the Key and Value, but in the production mode all I know is the "Key", the "Value" it will be generated and saved on the icloud.
An alternative solution that I can think is to retrieve all records for a specific reference type and from there find the one that I want by using the "Key" but I'm not sure what "NSPredicate" command should I use to retrieve all.
So I finaly figured it out how to solve the issue.
My alternative thought was to retrieve all records for a specific reference type, which I achieved that by using the following "NSPredicate"
var predicate = NSPredicate.FromValue(true);
var query = new CKQuery(recordType, predicate);
var result = await PublicDatabase.PerformQueryAsync(query, CKRecordZone.DefaultRecordZone().ZoneId);
This will return a CKRecord[] array including all of my saved records.
Finaly I loop throught the array and use my "Key" to check which record has a value like this
string ret = "";
for(nint i = 0; i < result.Length; ++i)
{
var record = (CKRecord)result[i];
var recordValue = record.ValueForKey((NSString)MyKey);
if (recordValue == null) continue;
if(!string.IsNullOrEmpty(recordValue))
return ret = recordValue;
}

SQLite exception deleting row using sqlite-net

I got tired to search so here it goes my first SO question hoping someone had the same problem and can help me
Goal
I am trying to store my application data with a SQLite database
Application description
Windows 8 app C# XAML with local SQLite database using SQLite for Windows Runtime Extension and sqlite-net library
Table definition
public class Product {
private int _id;
[SQLite.PrimaryKey, SQLite.AutoIncrement]
public int ID
{
get { return _id; }
set { _id = value; }
}
private string _date;
public string DATE
{
get { return _date; }
set { _date = value; }
}
private string _desc;
public string DESC
{
get { return _desc; }
set { _desc = value; }
}
}
Problem1
public int Insert (object obj) description says the following:
Inserts the given object and retrieves its auto incremented primary key if it has one.
However everytime I insert a row it return 1. I can sucessfully insert with a auto-incremet ID but somehow it does not return me its ID. Why?
Problem 2
I can insert new rows but not delete them
Working around problem 1 to get last row generated ID, I try to delete rows but with no success.
See this example test that always fails:
using (var db = new SQLiteConnection(Path.Combine(_path, _dbname)))
{
var p1 = new Product() { DESC = "insert1", DATE = DateTime.Now.ToString() };
db.Insert(p1);
p1.ID = 1;
var p2 = new Product() { DESC = "insert2", DATE = DateTime.Now.ToString() };
// I am sure that this row is getting ID 2, so it will not have a wrong ID
p2.ID = 2;
db.Insert(p2);
var p3 = new Product() { DESC = "insert3", DATE = DateTime.Now.ToString() };
db.Insert(p3);
p3.ID = 3;
db.Delete<Product>(p2);
}
As you can see I try to insert 3 rows and delete the second one. The rows are inserted but I get the following SQLite.SQLiteException exception:
unable to close due to unfinalized statements or unfinished backups
Why? I don't open other connections before and after that.
Thanks in advance
Solved
Problem 1
+1 and thanks for #Bridgey for pointing out that function does not match it description and for the relevant search
The function does not return ID as it says but it defines the object ID. So when I insert a new Product, Product.ID will have last inserted ID.
Problem 2
I changed db.Delete<Product>(p2); to db.Delete(p2); and now it works. SQLite-net correctly identify the row as Product. I still don't know why the unable to close due to unfinalized statements or unfinished backups exception was happening. If someone knows why tell me please.
I think for problem 2, the issue is that you are passing the Product object as the parameter for the Delete method. The documentation says: Deletes the object with the specified primary key. I think the following should work:
db.Delete<Product>(p1.ID);
Regarding problem 1, the code of the Insert method of the sqlite-net package ends:
var count = insertCmd.ExecuteNonQuery (vals);
if (map.HasAutoIncPK) {
var id = SQLite3.LastInsertRowid (Handle);
map.SetAutoIncPK (obj, id);
}
return count;
As you can see, count is returned, even if id is set.
EDIT: Actually, according to the author this is deliberate.
"Insert returns the number of rows modified. The auto incremented columns are stored in the object. Please see the doc comments."
https://github.com/praeclarum/sqlite-net/issues/37

Why would this query be returning null?

I am working on setting up database storage for a game project I am working on for school, and am at the very beginning of doing so. I am using MongoDB at the suggestion of our sponsor. I have successfully implemented inserting a list of names with individual indices, but I cannot get it to return them. The code I am using is as follows.
public string getName(int id) {
var query = Query.EQ("_index", id);
if (Names.FindOne(query) != null) return (Names.FindOne(query)).FirstName;
else return "Error";
}
I have now determined the problem is that the objects aren't being saved. My code for doing so is
public void storeName(string name, int number) {
Name Insert = new Name{FirstName = name, index = number};
var query = Query.EQ("_FirstName", name);
if (Names.FindOne(query) == null) { Names.Save<Name>(Insert); Console.WriteLine(Insert.index+" "+Insert.FirstName); }
else {Console.WriteLine("Bork"); }
}
And the Name object is automapped.
I solved my problem. The index and FirstName fields needed to not have the underscores.

Linq to Sql General Help - Insert Statement

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);

Categories

Resources