I've got a problem with adding data to my database. I have table for book, users and borrows. So, when user is logged in application and pick book, I want to add new data to borrows table. I thought it should be something like this(I call this method where click on chosen book):
public ActionResult AddIt([Bind(Include = "BorrowId,BorrowDate,GiveBackDate,BookId,UserId")] Borrows br))
{
br.BorrowDate = DateTime.Now;
br.BookId = int.Parse(Session["BookId"].ToString());
br.UserId = int.Parse(Session["UserId"].ToString());
if (ModelState.IsValid)
{
db.borrows.Add(br);
db.SaveChanges();
return RedirectToAction("Index");
}
return RedirectToAction("Index");
}
Getting UserId and BookId works, but there is something wrong while call this method. I got "Can't find resource" error. So, how should look that method? GiveBackDate is Nullable and I want it to be null when create record.
EDIT: I rebuilded project and that error disapeared.. But code still doesn't work properly. Seems like asp did not count BorrowIds. If database is empty I can save one record. But if one record is saved, next one goes with id 0 and generates error:
Violation of PRIMARY KEY constraint 'PK_BORROWS'. Cannot insert duplicate key in object 'dbo.Borrows'. The duplicate key value is (0).
The statement has been terminated.
Error at 84 row:
84: {
85: db.Borrows.Add(br);
86: db.SaveChanges();
87: return RedirectToAction("Index");
88: }
I call AddIt here, in BookController:
public ActionResult borrow(int id)
{
return RedirectToAction("AddIt", "Borrows");
}
Make sure the URL is correct. Controller, action and routing-wise
Make sure you're actually making a HTTP Post, since the action is mapped to a Post verb only.
I found a reason of violation primary key error. When I was creating database, I didn't add an IDENTITY property to my primary key BorrowID column. So, id should look like this:
CREATE TABLE [dbo].[Borrows] (
[BorrowId] INT IDENTITY (1, 1) NOT NULL,
Related
I want to insert a single record into my database using the Z Entity Framework Extensions and the SingleInsertAsync method. However, I need the ID of the freshly inserted entity. How can I get that? I can literally find no documentation for this method.
Here's my code:
Specification newSpecification = db.Specifications.Create();
newSpecification.ID_Feature = featureID;
newSpecification.Specification1 = specificationKey;
await db.Specifications.SingleInsertAsync(newSpecification);
int id = newSpecification.ID;
The variable id is obviously 0 after the insert. How can I get the actual ID there? Unfortunately, SingleInsertAsync doesn't return anything.
The SingleInsert works exactly like the BulkInsert method, so you can use the same documentation.
The method doesn't return the identity but should populate automatically the identity value.
If the Specification have the ID specified as identity, the value will be automatically populated.
See the following online example: https://dotnetfiddle.net/h9Psm7
I have a registration table in my database with a field RegistrationNumber which needs to be unique.
I am wondering about what is the best way to guarantee that I will provide unique number in every case.
What I do is in my Repository I save the new Registration, something like:
void IMyRepository.Repository(Registration registration)
{
registration.RegistrationNumber = _getNewRegistrationNumber();
dbContext.SaveChanges();
}
private string _getNewRegistrationNumber()
{
// what to do? get last registration number and increment? it could be
// either integers or integers mixed with letters.
}
What I'm worried about is if two people complete the registration form at the same time, I'm afraid that before the first one arrives at dbContext.SaveChanges(); the second one will enter the _getNewRegistrationNumber() function and might get the same RegistrationNumber.
Any advise?
[EDIT]
: GUID is too long
You have 3 options:
Use an computed Identiy column (Auto Increment) that will automaticly be created, if you insert a new record. The drawback is, you need a rountrip to the database, before you have an Number
Use a Guid
Use a unqiue index in your database and compute your own number. If the number already exist on save, you can catch a Exception.
The best way to guarant unique value is GUID:
void IMyRepository.Repository(Registration registration)
{
registration.RegistrationNumber = Guid.NewGuid().ToString();
dbContext.SaveChanges();
}
I'm writing code in ASP.NET but it's not a language related question. Every time when I write a web application and I display some data from database using razor view I have this problem. For example I have simple table with Id and Name in my database. I want to display a table with Names using EditorFor fields. User can edit all the data and save it. So I use row Id as EditorFor Id, read input values in javascript method, use WebMethod to pass them to Controller and save changes to database. But in this case I can change EditorFor Id in Firebug and pass changes with wrong ids. What's the way to edit data in that case? I don't want to click edit link and redirect user to edit page when he can edit one row. I have 5 rows in database with Names and I want to edit all of them at once.
That's some kind of security, and you must add security method in this situation.
One way is to use RBAC method for your security structure. For example:
Create a table and name it user_groups, then create table of users that has and foreign key to user_groups
Then also add the foreign key to your " simple table "(that has id and name) to user_groups, that represent witch user_groups can update the row,
I this that's clear. When someone want to edit a row, you check if that user has permission to change the row or not?
You can search term "Role Base Access Control" in asp mvc,
Also something useful here:
http://www.webdevbros.net/2009/12/16/role-based-access-control-in-asp-net-mvc/
[HttpPost]
public ActionResult EditEmailTemplate(EmailTemplate_Mst emailTemplate_Mst, string Command, int id = 0)
{
try
{
EmailTemplate_Mst et = _repository.GetEmailById(id);
if (Command == "Update")
{
et.Title = emailTemplate_Mst.Title;
et.EmailTemplate_Content = emailTemplate_Mst.EmailTemplate_Content;
et.EmailTemplate_LastModifyBy = Convert.ToInt64(Session["UserId"].ToString());
et.EmailTemplate_LastModifyDate = DateTime.Now;
_repository.UpdateEmail(et);
return RedirectToAction("ViewEmailTemplate");
}
}
catch (Exception)
{
ModelState.AddModelError("", "Unable to save changes. Try again, and if the problem persists see your system administrator.");
}
return View(new { id = emailTemplate_Mst.EmailTemplate_Id });
}
http://www.c-sharpcorner.com/UploadFile/4d9083/creating-insert-update-and-delete-application-in-mvc-4-using/
New with EDS. VWD 2011.
Adding vehicles to my vehicle file. PK is Company number (char 5) and vehicle code (char 15). Using a details view with only the main keys and the entitydatasource is defined and working with datakeynames.
In the EDS inserting event, i want to go into the file, and see if what is entered, is there first. It adds perfect if a new code, and of course bombs is duplicate.
Old visual foxpro programmer, just learning this. The EDS is already opened with the correct file in the database and everything.. maybe if I do a count() "where" condition, and if 0, maybe new... I really just want some foxpro SEEK COMPANYNUMBER+VEHCODE and if not there, allow to add...
Thanks for any input. It is 2:19am in the morning.. fun teaching myself something new...lots of hours..
Frank C :)
You 'could' go out and check to see if the record already exists, and than add it only if it does not; perhaps a better way is to have a unique index on that field combination so that it would be impossible to save duplicate records, and then let EF tell you when the save changes has failed. This will prevent you from making two calls to the DB on every insert attempt.
Example:
try
{
if (ModelState.IsValid)
{
db.Vehicles.Add(vehicle);
db.SaveChanges();
}
}
catch (DataException)
{
//Log the error (add a variable name after DataException)
ModelState.AddModelError("", "Unable to save changes. Try again, and if the problem persists see your system administrator.");
}
First of all, there is no chance that this is a multi-user issue, as I'm working locally on a dev version of the database.
I am getting the not very explanatory Row not found or changed error being thrown when I perform db.SubmitChanges(). If I break the execution just before the SubmitChanges() occurs, I can check in SQL Server Management Studio and the row does exist!
Here's the code for the whole function, just to put it in context for anyone who wants to help, but the problem line is right at the end (line 48).
Update This is a really odd one: the error is caused by updating matchingTrans.Url (see penultimate line of code). Commenting out this line doesn't throw the error - even if the matchingTrans.Title still gets updated.
private static void MenuItemUpdate(int languageId, NavigationItem item)
{
using (var db = DataContextFactory.Create<MyDataContext>())
{
// Select existing menu item from database.
var dbItem =
(from i in db.MenuItems
where i.Id == item.Id
select i).Single();
// Obtain ID of link type.
dbItem.FkLinkTypeId = GetLinkTypeByName(
Enum.GetName(typeof (NavigationItemLinkType), item.LinkType)).Id;
// Update the Link field with what is given.
dbItem.Link = item.Link;
db.SubmitChanges();
// Item already exists and needs editing.
// Get associated translations.
var trans =
from t in db.MenuItemTranslations
where t.FkMenuItemId == item.Id
select t;
// If translation exists for given language, edit it.
var matchingTrans =
(from t in trans
where t.FkLanguageId == languageId
select t).SingleOrDefault();
if (matchingTrans == null)
{
// No matching translation - add one.
var newDbTrans = new MenuItemTranslation
{
FkMenuItemId = item.Id,
FkLanguageId = languageId,
Title = item.Title,
Url = item.FriendlyUrl
};
db.MenuItemTranslations.InsertOnSubmit(newDbTrans);
db.SubmitChanges();
}
else
{
// Matching translation - edit it.
matchingTrans.Title = item.Title;
matchingTrans.Url = item.FriendlyUrl;
db.SubmitChanges();
// WTF ERROR: Row not found or changed.
}
}
}
Looking at the SQL Profiler output, it helped me figure out the answer to this. There was a bad piece of SQL being generated which ended with WHERE 0 = 1 ... an obvious error.
It turns out that the field had simply been changed to allow nulls by another developer, and the Linq-to-SQL file hadn't been updated accordingly.
In short, if the Row not found or changed error message appears to be generated for no reason, make sure your database schema exactly matches your .dbml file else you'll get this error message on any fields that have slightly differing schemas.
Take a look at the connection property "No Count" at sql server server level
1. Right click on Sql server connection in Object Explorer -->Property
2. Go to Connection Tab/Page
3. Look for the Default connection option "no count"
4. Make sure this option is not checked.
Another possibility that I've found to add to the excellent list of answers here:
When using a not-nullable column in a database - then mapping that to a datatype that is intrinsically nullable (in this example DB type is LONG BLOB NOT NULL mapped to a byte array in c#) you can end up in a situation where updating the database with the exact same byte array causes this error to be thrown.
Example: You have a website that allows the user to upload an image to the database. Your table has a blob (image in sql server, whatever) that is not nullable. The user chooses to update the record with the exact same image that is already there. The update check will fail. I fixed this by first doing a .SequenceEqual() check and then only calling .SubmitChanges() on the context object if the incoming byte array was not equal to the existing one.
I had this issue even when the database schema and dbml matched exactly. The issue was I was trying to change an entity and insert entities in a single SubmitChanges statement. I fixed it by doing SubmitChanges on each operation instead of all at once.
This was all in a transaction scope so that may have something to do with it but I'm not sure.