Error inserting into database using entity framework - c#

I am going to get mad. I have a so simple code but it doesn't work.
I have tested every thing and I can't understand the reason.
The code is like this:
FataDBEntities model = new FataDBEntities();
UserAccount nua = new UserAccount();
nua.username = username;
nua.pass = password;
nua.email = mailaddress;
nua.activated = false;
model.UserAccounts.Add(nua);
try
{
model.SaveChanges();
}
catch (Exception)
{
throw;
}
string activationCode;
try
{
activationCode = genActivationCodeAndMail(mailaddress, username);
}
catch (Exception)
{
throw;
}
ActivationCode ac = new ActivationCode();
ac.code = activationCode;
ac.expiration_date = DateTime.Now.AddDays(1);
nua = model.UserAccounts.Single(p => p.username == username);
ac.wichUser = nua.ID;
model.ActivationCodes.Add(ac);
try
{
model.SaveChanges();
}
catch (Exception)
{
throw;
}
and the model is like this :
The error is with second insertion ... the first one works fine.
Additional information: Unable to update the EntitySet 'ActivationCode' because it has a DefiningQuery and no element exists in the element to support the current operation.
Please help...

According to this SO article, this error can occur if the entity set is mapped from the database view, custom database query or if database table does not have primary key.
This has happened to me before, and I used that same article to fix the issue :)

Related

SubmitChanges not updating, but inserts new record. LINQ to SQL

I am having difficulties UPDATING the databes via LINQ to SQL, inserting a new record works fine.
The code correctly inserts a new row and adds a primary key, the issue I am having is when I go to update (chnage a value that is already in the database) that same row the database is not updating, it is the else part of the code that does not work correctly. This is strange b/c the DB is properly connected and functioning through the fact that the DataContext inserts a new row with no issues. Checking the database confirms this.
This is the code,
using System;
using System.Collections.Generic;
using System.Linq;
using Cost = Invoices.Tenant_Cost_TBL;
namespace Invoices
{
class CollectionGridEvents
{
static string conn = Settings.Default.Invoice_DbConnectionString;
public static void CostDataGridCellEditing(DataGridRowEditEndingEventArgs e)
{
using (DatabaseDataContext DataContext = new DatabaseDataContext(conn))
{
var sDselectedRow = e.Row.Item as Cost;
if (sDselectedRow == null) return;
if (sDselectedRow.ID == 0)
{
sDselectedRow.ID = DateTime.UtcNow.Ticks;
DataContext.Tenant_Cost_TBLs.InsertOnSubmit(sDselectedRow);
}
else
{
// these two lines are just for debuging
long lineToUpdateID = 636154619329526649; // this is the line to be updated primary key
long id = sDselectedRow.ID; // this is to check the primary key on selected line is same
// these 3 lines are to ensure I am entering actual data into the DB
int? amount = sDselectedRow.Cost_Amount;
string name = sDselectedRow.Cost_Name;
int? quantity = sDselectedRow.Cost_Quantity;
sDselectedRow.Cost_Amount = amount;
sDselectedRow.Cost_Name = name;
sDselectedRow.Cost_Quantity = quantity;
}
try
{
DataContext.SubmitChanges();
}
catch (Exception ex)
{
Alert.Error("Did not save", "Error", ex);
}
}
}
}
}
And I am calling the method from this,
private void CostDataGrid_RowEditEnding(object sender, DataGridRowEditEndingEventArgs e)
{
CollectionGridEvents.CostDataGridCellEditing(e);
}
The lineToUpdateID is copied dirrectly from the database and is just there to check against the currently selected rows primary key is the same, so I know I am trying to update the same row.
I have looked through as many of the same type of issues here on SO , such as this one Linq-to-Sql SubmitChanges not updating fields … why?. But still no closer to finding out what is going wrong.
Any ideas would be much appreciated.
EDIT: Cost is just short hand of this using Cost = Invoices.Tenant_Cost_TBL;
You cannot do that. You need to get the record out of the database and then update that record. Then save it back. Like this:
else
{
// first get it
var query =
from ord in DataContext.Tenant_Cost_TBLs
where ord.lineToUpdateID = 636154619329526649
select ord;
// then update it
// Most likely you will have one record here
foreach (Tenant_Cost_TBLs ord in query)
{
ord.Cost_Amount = sDselectedRow.Cost_Amount;
// ... and the rest
// Insert any additional changes to column values.
}
}
try
{
DataContext.SubmitChanges();
}
catch (Exception ex)
{
Alert.Error("Did not save", "Error", ex);
}
Here is an example you can follow.
Or you can use a direct query if you do not want to select first.
DataContext.ExecuteCommand("update Tenant_Cost_TBLs set Cost_Amount =0 where ...", null);
Your object (Cost) is not attached to DB context. You should attach it then save changes. Check solution here

Insert with Linq-to-SQL sometimes fails

I have a project that inserts personal information to a table and details into another table. But sometimes personal information cannot be recorded, however details are recorded. As below code part, firstly personal information are inserted, then details. But sometimes personal information doesn't get saved and userId returns 0, So details are saved. I don't know why it doesn't work. Any idea?
public int ConferenceIdyeGoreKisiBilgileriniKaydet(string orderId)
{
KisiselBilgilerBal kisiBilgileri = (KisiselBilgilerBal)Session["kisiselBilgilerSession"];
registrationCode = GenerateGeristrationCode();
string toplamMaliyet = Session["toplamOdeme"].ToString();
PersonalInformation.SavePersonalInformations(kisiBilgileri, registrationCode,conferenceName);
int userId = AuthorPaperDetaylari.AdVeSoyadaGoreIdGetir(kisiBilgileri.f_name, kisiBilgileri.l_name);
AuthorPaperDetaylari.SaveAuthorPaperDetails(authorPaperDetay, userId); // save details via userId.
return userId;
}
This method saves personal information.
public static void SavePersonalInformations(KisiselBilgilerBal kisiBilgileri,string registrationCode,string conferenceName)
{
try
{
string cs = ConfigurationManager.AppSettings["SiteSqlServer"];
DBDataContext db = new DBDataContext(cs);
DBpersonalInformation personalInfo = new DBpersonalInformation();
personalInfo.f_name = kisiBilgileri.f_name;
personalInfo.l_name = kisiBilgileri.l_name;
personalInfo.university_affiliation = kisiBilgileri.university_affiliation;
personalInfo.department_name = kisiBilgileri.department_name;
personalInfo.address1 = kisiBilgileri.address1;
personalInfo.address2 = kisiBilgileri.address2;
personalInfo.city = kisiBilgileri.city;
personalInfo.state = kisiBilgileri.state;
personalInfo.zipCode = kisiBilgileri.zipCode;
personalInfo.country = kisiBilgileri.country;
personalInfo.phone = kisiBilgileri.phone;
personalInfo.email = kisiBilgileri.email;
personalInfo.orderId = kisiBilgileri.orderId;
personalInfo.registrationCode = registrationCode;
personalInfo.date = DateTime.Now;
personalInfo.conferenceName = conferenceName;
db.DBpersonalInformations.InsertOnSubmit(personalInfo);
db.SubmitChanges();
}
catch (Exception)
{
}
}
This method saves details
public static void SaveAuthorPaperDetails(AuthorPaperDetailsBal authorPaperDetay, int userId)
{
try
{
string cs = ConfigurationManager.AppSettings["SiteSqlServer"];
DBWebDataContext db = new DBWebDataContext(cs);
DBAuthorPaperDetail authorPaperDetail = new DBAuthorPaperDetail();
authorPaperDetail.paper_title = authorPaperDetay.paperTitleDetails;
authorPaperDetail.conference_maker_id = authorPaperDetay.confMakerId;
authorPaperDetail.additional_paper_title = authorPaperDetay.additionalPprTtle;
authorPaperDetail.areYouMainAuthor = authorPaperDetay.mainAuthor;
authorPaperDetail.feeForFirstAuthorPaper = authorPaperDetay.registerFeeForFirstAuthor;
authorPaperDetail.feeForAdditionalPaper = authorPaperDetay.regFeeForAdditionalPape;
authorPaperDetail.feeForParticipCoAuthors = authorPaperDetay.regFeeForCoAuthors;
authorPaperDetail.userId = userId;
authorPaperDetail.firstCoAuthorName = authorPaperDetay.firstCoAuthor;
authorPaperDetail.secondCoAuthorName = authorPaperDetay.secondCoAutho;
authorPaperDetail.thirdCoAuthorName = authorPaperDetay.thirdCoAuthor;
authorPaperDetail.toplamOdeme = authorPaperDetay.toplamMaliyet;
db.DBAuthorPaperDetails.InsertOnSubmit(authorPaperDetail);
db.SubmitChanges();
}
catch (Exception)
{
}
}
I don't know why it doesnt work. Any idea?
...
catch (Exception)
{
}
Well, that explains pretty much everything... don't do this. Ever. The database layer is trying to tell you what the problem is, and you are sticking your fingers in your ears, hoping that'll make it go away. If I had to guess: maybe an occasional timeout due to being blocked by another SPID.
If you can't do anything useful or appropriate with an exception, just let it bubble to the caller. If it gets to the UI, tell the user about it (or just log the issue internally and tell the user "There was a problem").
Also, a LINQ-to-SQL data-context is IDisposable; you should have using statement around db.
In addition to Marc's answer... You are calling SubmitChanges twice. If you want atomic data storage, you should call it once. You can use relational properties to create an object graph, and submit the whole graph at once.
public void SaveParentAndChildren()
{
using (CustomDataContext myDC = new CustomDataContext())
{
Parent p = new Parent();
Child c = new Child();
p.Children.Add(c);
myDC.Parents.InsertOnSubmit(p); //whole graph is now tracked by this data context
myDC.SubmitChanges(); // whole graph is now saved to database
// or nothing saved if an exception occurred.
} //myDC.Dispose is called for you here whether exception occurred or not
}

Unable to update record in LINQ to SQL

Need help in updating records using LinQ.
I tried updating the record, but it does not display in the database.
The primary key is set in both db and LinQ dbml file.
Below are the codes:
RPHContrib _phContrib = new RPHContrib();
_phContrib.PHTableNo = phContrib.PHTableNo;
_phContrib.AmountFrom = phContrib.AmountFrom;
_phContrib.AmountTo = phContrib.AmountTo;
_phContrib.EmployeePH = phContrib.EmployeePH;
_phContrib.EmployerAmt = phContrib.EmployerAmt;
_phContrib.IsActive = phContrib.IsActive;
_phContrib.CreatedByNo = phContrib.CreatedByNo;
_phContrib.CreatedDate = phContrib.CreatedDate;
_phContrib.ModifiedByNo = SessionStateController.OnlineUserNo;
_phContrib.ModifiedDate = DateTime.Now;
LINQHelper.Instance.GenericDataContext<HRWizardDataContext>(GetDataContext(false));
LINQHelper.Instance.Update<RPHContrib>(_phContrib);
public bool Update<T>(T obj) where T : class, ICommon, new()
{
using (var db = GetDBDataContext())
{
db.Connection.Open();
DbTransaction trans = db.Connection.BeginTransaction();
db.Transaction = trans;
// Populate object log
obj.IModifiedDate = DateTime.Now;
try
{
Detach<T>(obj); // Detach LINQ entity from the original DataContext before attaching to the new one
db.GetTable<T>().Attach(obj, true);
db.SubmitChanges();
db.Transaction.Commit();
}
catch (Exception ex)
{
db.Transaction.Rollback();
// TODO: Put error logging code here
throw ex;
}
finally
{
if (db.Connection != null)
{
db.Connection.Close();
db.Connection.Dispose();
}
}
}
return true;
}
When you are adding a new recored use InsertOnSubmit(Entity), afterwhich any Auto Numbers (eg. primary) will be updated on your object automatically after you call SubmitChanges().
Use Attach(Entity) when you are updating an entity. Make changes to the entity after you have attached it. Making changes before you attach it to the Context will not trigger the Update SQL as the context will think there is nothing to update.
You need to do insertonsubmit(obj); before submitchanges();

Help with Exception Handling in ASP.NET C# Application

yesterday i posted a question regarding the Exception Handling technique, but i did'nt quite get a precise answer, partly because my question must not have been precise.
So i will ask it more precisely.
There is a method in my BLL for authenticating user. If a user is authenticated it returns me the instance of the User class which i store in the session object for further references.
the method looks something like this...
public static UsersEnt LoadUserInfo(string email)
{
SqlDataReader reader = null;
UsersEnt user = null;
using (ConnectionManager cm = new ConnectionManager())
{
SqlParameter[] parameters = new SqlParameter[1];
parameters[0] = new SqlParameter("#Email", email);
try
{
reader = SQLHelper.ExecuteReader(cm.Connection,
"sp_LoadUserInfo", parameters);
}
catch (SqlException ex)
{
//this gives me a error object
}
if (reader.Read())
user = new UsersDF(reader);
}
return user;
}
now my problem is suppose if the SP does not exist, then it will throw me an error or any other SQLException for that matter. Since this method is being called from my aspx.cs page i want to return some meaning full message as to what could have gone wrong so that the user understands that there was some problem and that he/she should retry logging-in again.
but i can't because the method returns an instance of the User class, so how can i return a message instead ??
i hope i made it clear !
thank you.
There are a lot of approaches you could take here, an easy one would be to return null if you can't find an appropriate user object (because of the exception). then in the calling code you just test for null and if it is null display an error message.
for example
User u = LoadUserInfo(email);
if(u == null)
{
ErrorLabel.Text = "Could not log in.";
ErrorLabel.Visible = true;
//.... or some other notification
}
else
{
//... normal load
}
that would be a basic way to go about it.
There are lot of approaches you have but in your method you declared "SqlDataReader reader = null;" some times you will get error at if condition "if (reader.Read())" because you declared as null.
public static UsersEnt LoadUserInfo(string email)
{
SqlDataReader reader = new SqlDataReader();
UsersEnt user = null;
using (ConnectionManager cm = new ConnectionManager())
{
SqlParameter[] parameters = new SqlParameter[1];
parameters[0] = new SqlParameter("#Email", email);
try
{
reader = SQLHelper.ExecuteReader(cm.Connection,
"sp_LoadUserInfo", parameters);
if (reader.Read())
user = new UsersDF(reader);
}
catch (SqlException ex)
{
user.Exception=ex.Message;
}
}
return user;
}
and then
User us = LoadUserInfo(email);
if(us.Exception != null)
{
ErrorLabel.Text = "Could not log in.";
ErrorLabel.Visible = true;
//.... or some other notification
}
else
{
//... normal load
}
i think it will work.

Why can't I insert record with foreign key in a single server request?

I'm tryring to do a simple insert with foreign key, but it seems that I need to use db.SaveChanges() for every record insert. How can I manage to use only one db.SaveChanges() at the end of this program?
public static void Test()
{
using (var entities = new DBEntities())
{
var sale =
new SalesFeed
{
SaleName = "Stuff...",
};
entities.AddToSalesFeedSet(sale);
var phone =
new CustomerPhone
{
CreationDate = DateTime.UtcNow,
sales_feeds = sale
};
entities.AddToCustomerPhoneSet(phone);
entities.SaveChanges();
}
}
After running the above code I get this exception:
System.Data.UpdateException: An error occurred while updating the entries. See the InnerException for details. The specified value is not an instance of a valid constant type
Parameter name: value.
EDIT: Changed example code and added returned exception.
Apperantly using UNSIGNED BIGINT causes this problem. When I switched to SIGNED BIGINT everything worked as it supposed to.
I tried to do this "the right way":
And then I wrote this little test app to scan a directory, store the directory and all its files in two tables:
static void Main(string[] args)
{
string directoryName = args[0];
if(!Directory.Exists(directoryName))
{
Console.WriteLine("ERROR: Directory '{0}' does not exist!", directoryName);
return;
}
using (testEntities entities = new testEntities())
{
StoredDir dir = new StoredDir{ DirName = directoryName };
entities.AddToStoredDirSet(dir);
foreach (string filename in Directory.GetFiles(directoryName))
{
StoredFile stFile = new StoredFile { FileName = Path.GetFileName(filename), Directory = dir };
entities.AddToStoredFileSet(stFile);
}
try
{
entities.SaveChanges();
}
catch(Exception exc)
{
string message = exc.GetType().FullName + ": " + exc.Message;
}
}
}
As you can see, I only have a single call to .SaveChanges() at the very end - this works like a charm, everything's as expected.
Something about your approach must be screwing up the EF system.....
it might be related with the implementation of AddToSalesFeedSet etc..
there is chance that you are doing commit inside ?
any way, my point is that i encountered very close problem, was tring to add relation to new entity with existed entity that been queried earlier - that has unsigned key
and got the same exception;
the solution was to call Db.collection.Attach(previouslyQueriedEntityInstance);

Categories

Resources