Cannot insert duplicate key - asp.net-mvc

I am getting this error ...
Violation of PRIMARY KEY constraint 'PK_Members'. Cannot insert duplicate key in object 'dbo.Members'.
The statement has been terminated.
When I try to use the Membership and Role Providers in ASP.NET MVC. It happens when calling the GetUser method from inside the RoleProvider.
var member = System.Web.Security.Membership.GetUser(email) as Models.Member;
//var member = (
// from m in DataContext.Members
// where m.Email == email
// select m).Single();
var role = (
from r in DataContext.Roles
where r.Name == roleName
select r).Single();
member.Groups.Add(new Models.Group(role));
DataContext.SubmitChanges();

It looks like the problem is in the code
member.Groups.Add(new Models.Group(role));
Based on the error message returned by the sql, Read operation like GetUser won't throw this type of error.

I suspect it's because you are adding a group that exists already.
Maybe you should check for the existance of the role before trying to add it.
Hope this helps.

A good way to debug this is to use SQL profiler to determine what SQL code is being run against the database.
I would suspect you are trying to save a record somewhere that has the same primary key already in the database.
SQL Profiler = http://msdn.microsoft.com/en-us/library/ms181091.aspx

Are you sure you are not trying to enter a number into the PRIMARY KEY field that is already there? If it is auto_increment, just enter 0 and it will make the value of that field, the last number+1
Hope this helps :)

If the exception is an SqlException you might get its error number for duplicate records which is 2627. You might catch the exception and verify it and display and manage any error accordingly. I Hope this helps.
catch (SqlException ex)
{
if (ex.Number == 2627)
{
MessageBox.Show("This record exists: "+ex.Message, "Error");
}
else
{
MessageBox.Show(ex.Message, "Error")
}
}

I am a newbie at this but I am going to give this a try, sorry if it doesn't work for you.
I think that instead of using,
member.Groups.Add(new Models.Group(role));
You should use the following (if you are updating the database):
member.Groups.Entry(new Models.Group(role));
And if the above code doesn't work, try this (if you are adding to the database):
// First, search for the particular obj you want to insert
var checkModels = member.Groups.Find(new Models.Groups(roles));
// If the obj doesn't already exist, add it to the database
if(checkModels == null){
member.Groups.Add(new Models.Group(role));
}
// If the obj does exist already, then update it
else{
member.Groups.Entry(new Models.Group(role)).State = EntityState.Modified;
}

Related

Documentdb ReadDocumentAsync doesn't work

I have the following F# code attempting to get a user document from my documentdb database and it doesn't work. Is anyone else experiencing problems using the ReadDocumentAsync method? I am able to successfully to query my user documents with the CreateDocumentQuery method. Any help is greatly appreciated. I use my database and collection ids in place of the empty strings in the code snippet
let getUserDatabaseModel (documentClient : DocumentClient) originiatorId =
async {
let databaseId = ""
let collectionId = ""
let documentUri = UriFactory.CreateDocumentUri(databaseId, collectionId, originiatorId)
let! userDatabaseModel =
documentClient.ReadDocumentAsync(documentUri)
|> Async.AwaitTask
return userDatabaseModel
}
|> Async.RunSynchronously
Update
If I use the _rid instead of the id I get the data back. To clarify the ReadDocumentAsync seems to work using the _rid but throws the error below when using the id.
mscorlib: Exception has been thrown by the target of an invocation.
FSharp.Core: One or more errors occurred. Microsoft.Azure.Documents.Client:
The value 'left blank intentionally' specified for
query '$resolveFor' is invalid
I posted a while back on the documentdb github issues page, problems I was having with ReplaceDocumentAsync.
https://github.com/Azure/azure-documentdb-dotnet/issues/113
I wasn't too concerned about the fix because there was UpsertDocumentAsync. This issue seems to be related, or maybe their relation is just me! not being able to figure out what I'm doing wrong.
CreateDocumentUri needs consistent ids, either all ids or all _rids for the database, collection, and document

Where not null using Linq

I have a mySQL database with a Website field that is of type VarChar. Some of these fields will be null on the database.
I have an MVC application that I sending the database information to.
I am trying to set up a filter on the Index page so I can filter by certain columns. I am using the Request.QueryString to do this.
switch (Request.QueryString["FilterOptionSelect"])
{ case "CountyName":
if (!string.IsNullOrEmpty(filteredText))
{
filteredText = filteredText.ToUpper();
var modelFiltered = from n in model
where n.CountyName.ToUpper().Contains(filteredText)
select n;
return View(modelFiltered);
}
break;
case "Website":
if (!string.IsNullOrEmpty(filteredText))
{
filteredText = filteredText.ToUpper();
var modelFiltered = from n in model
where n.CountyWebsite.ToUpper().Contains(filteredText)
select n;
return View(modelFiltered);
}
break;
}
The only problem I have is on the Website case. It gives me a Object reference not set to an instance of an object. on the WHERE CLAUSE of the Website case. When I debug, my model is not null (it has 130+ items inside...some with website info and some without website info).
I have already tried using the Lambda method (which had the same problem). I have also tried using where n.CountyWebsite.ToUpper().Contains(filteredText) && n.CountyWebsite != null which did not work either.
You were on the right track with your second attempt, but you need to switch the order of those statements.
where n.CountyWebsite != null && n.CountyWebsite.Contains(filteredText)
Just like all the other && operators, you don't want to evaulate any websites that are null, so do that operation first.
Also, .Contains in EF automatically is case-insensitive, so you don't need the ToUpper().
Try this, I think this will solve.
!String.IsNullOrEmpty(n.CountyWebsite) && n.CountyWebsite.Contains(filteredText)

loop through model in mvc razor code behind

I am working on MVC4 App, and I am stuck at one point, I tried using google to help me, but without success. This might be more simple then I think, but coming from web forms and shifting to mvc is "painful" sometime.
I am trying to loop through the model I have and get the values stored in that model. I tried few approaches but I am getting an error everytime. This is what I have:
var modelAgentFilter = from s in _aa.Agents
where s.COUNTER == Convert.ToInt32(AgentID)
select s;
if (modelAgentFilter != null)
{
ViewBag.FirstName = // Get FirstName object here
}
Thanks in advance for your comments.
Laziale
EDIT:
I did include for loop like this:
if (modelAgentFilter != null)
{
foreach (var property in modelAgentFilter)
{
string test = property.ADDRESS;
}
}
But when the compiler will reach the foreach step I am getting this error: "LINQ to Entities does not recognize the method 'Int32 ToInt32(System.Object)' method, and this method cannot be translated into a store expression."
I can get to the properties of the var model using that foreach look but as soon as the compiler will try to loop the model that error pops up.
Thanks again
LINQ to Entities does not recognize any methods. You can't use even ToString() in LINQ expression. You need first convert your value and than add it in LINQ.
In your example you need to do something like following:
var _agentID = int.Parse(AgentID);
var modelAgentFilter = from s in _aa.Agents
where s.COUNTER == _agentID
select s;

saveChanges fails if key has a Date field (version 1.2.8)

We have an entity with three key fields, one of which is a date (don't ask - its a summary view with no other obvious key).
Breeze is throwing "This key is already attached" error when processing the response from the server after saving changes to the aforementioned entity.
The problem occurs in MergeEntity after saving changes. It seems that the initial lookup fails to find the entity on the client, so it tries to add it again resulting in the error.
Near the top of MergeEntity we find the following line...
var entityKey = EntityKey._fromRawEntity(node, entityType);
...which returns an entityKey._keyInGroup == "1535:::44:::2013-02-28T11:00:00.000Z". Note the third key field which looks like the JSON date string.
Later, when the new entity is (incorrectly) created its entityKey._keyInGroup == "1535:::44:::Fri Mar 01 2013 00:00:00 GMT+1300 (New Zealand Daylight Time)". Now the third field looks like a true javascript date.
The error finally occurs when we hit this line...
attachEntityCore(em, targetEntity, EntityState.Unchanged);
...get the "This key is already attached" error as the entity we've just saved was obviously already in the client cache all along.
Update: My hacks to Breeze to get this working...
1) I changed the _fromRawEntity function to check for dates and convert them properly so we get the same key values that are produced later for the real entity. (This code was copied from the updateEntity function so should behave identically).
ctor._fromRawEntity = function (rawEntity, entityType) {
var keyValues = entityType.keyProperties.map(function (p) {
var val = rawEntity[p.nameOnServer];
if (p.dataType.isDate && val) {
if (!__isDate(val)) {
val = DataType.parseDateFromServer(val);
}
}
return val;
});
return new EntityKey(entityType, keyValues);
};
2) Breeze now found the entity after saving changes but... I then got an error when Breeze tried to update the entities properties using the values returned from the server. I suspect this is due to an issue in the defaultPropertyInterceptor function which was checking to see if the property value had changed...
// exit if no change
if (newValue === oldValue) {
return;
}
This will always return false when comparing dates so I hacked this line to be:
if (newValue === oldValue || (dataType && dataType.isDate && newValue && oldValue && newValue.valueOf() === oldValue.valueOf())) {
return;
}
From my initial testing everything seems to be working but I'd greatly appreciate any thoughts from folks who are more familiar with breeze :)
Updated: Perhaps the last snippet would be more breeze-ish as...
// exit if no change
var comparable = dataType && getComparableFn(dataType);
if (newValue === oldValue || (comparable && comparable(newValue) === comparable(oldValue))) {
return;
}
...although that adds a bit more code considering it is running in every property set.
Edit: This was fixed in Breeze v1.3.0, available now.
Agreed, this is a bug! It will be fixed in the next release, out early next week. ( and we now have a test that involves a date as part of a primary key :)
and thanks for finding, analyzing and reporting it. The analysis really helped.

The member with identity ' ' does not exist in the metadata collection.\r\nParameter name: identity

I simplified the code a little while trying to debug:
[HttpPost]
public ActionResult Register(User model)
{
DateTime bla = new DateTime(2012, 12, 12);
try
{
User user = new User
{
gid = 1,
cid = 1,
firstName = model.firstName,
lastName = model.lastName,
email = model.email,
username = model.username,
password = model.password,
creationDate = bla,
active = 1
};
myContext.Users.AddObject(user);
myContext.SaveChanges();
}
catch (Exception ex)
{
throw ex;
}
return View();
}
The values are transmited accordingly. Users table:
[id] [int] IDENTITY(1,1) NOT NULL,
[cid] [int] NULL,
[gid] [int] NULL,
[firstName] [nvarchar](100) NOT NULL,
[lastName] [nvarchar](100) NOT NULL,
[email] [nvarchar](max) NOT NULL,
[username] [nvarchar](100) NOT NULL,
[password] [nvarchar](100) NOT NULL,
[creationDate] [datetime] NOT NULL,
[active] [int] NOT NULL,
CONSTRAINT [PK_Users_3213E83F0AD2A005] PRIMARY KEY CLUSTERED
I deleted all the foreign keys to be sure that nothing affects it. I am qute certain that at a previous moment it was working, but now I can not figure where the issue is.
It crashes while performing the savechanges:
{"An error occurred while updating the entries. See the inner exception for details."}
{"The member with identity '' does not exist in the metadata collection.\r\nParameter name: identity"}
I had the same error being thrown when I try to insert using EF, the error was
The member with identity 'Id' does not exist in the metadata collection.\r\nParameter name: identity
It wasn't obvious at first but the exception message was very concise because my database knows the column Id int but the property created for the object on my code was int ID so coming back to named mapping, Id is not mapped to ID.
So when an object with property ID is sent to database that only know Id you will get the above error.
I hope this helps, thanks
The issue was reproducing because of a trigger that was on the users table. Removed it and the issue is not reproducing anymore.
There is probably a trigger on the table being updated and it returns output. The output is thrown away but it conflicts with EF. Such output is often used to debug triggers (and forgotten to delete later):
select 'trigger called, i am here'
or there can be missing variable:
select column
instead of
select #variable=column
I think that the best solution is in this post. I used the 3rd option and works.
Here I report the reply in the link:
The issue could be related to a "instead of insert" trigger on one of
your tables.
The EF framework is performing validation on the inserted row of data
by calling scope_identity(). However, an "instead of insert" trigger
will change the context of the insertion in such a way that the EF
system's call to scope_identity will return null.
A couple ways around this:
Use a stored procedure to insert the data ( not tested )
Remove the instead of insert trigger ( triggers can cause other problems, so some people argue not to use them) ( tested, works!)
Turn off validation in the EF framework, so: context.Configuration.ValidateOnSaveEnabled = false ( tested, works!)
I had this same error today and spent a few frustrating hours trying to figure it out.
I was using Entity Framework to insert a record with an identity column into a SQL server database table. Simple enough.
The table had a trigger on it which in turn ran a stored procedure. The stored procedure had a line in it:
select newid()
This is the line that broke Entity Framework.
For tables with identity columns, Entity Framework expects to be returned a single row with a single field that is the identity column.
it's because of trigger pass back value to EF
if you are using trigger. in my problem i must check a value by selecting from other table and using of 'select' cause error in EF, so you must replace 'select' with 'set'.
you can not use this code.
select #any= any from tablename
you should use set instead of select
set #any= (select any from tablename)
Somedays, I hate M$.
The member with identity 'ChangeID' does not exist in the metadata collection.
Parameter name: identity
I've spent two days trying to get around this.
I'm using MVC.
To get all the data I need in one fell swoop, I created a view of the table in the DB for this application, and tables in other databases. (You may update views, with some constraints.)
I do a get, and all my data is present in the record, keys, descriptions, foreign keys, etc.
I created triggers on my view, to update the portion of the view that came from the local table.
Instead of Delete worked fine.
Instead of Update worked fine.
This error kept raising it's head on Instead of Insert. I could NOT get the insert trigger to successfully insert into my table. If I ran an insert on the view, with all fields provided in the SQL Management Studio, it worked fine. I know the exact values being passed because I ran SQL Server Profiler to see the code being passed.
But when the app attempted the update, it failed with The member with identity 'ChangeID' does not exist in the metadata collection.
Clue up above, someone said, "MVC expects table key to be ID"
I renamed ChangeID as ID in my view, changed it in the App, and BAM! Now it works.
What did NOT work:
db.Configuration.ValidateOnSaveEnabled = false;
adding a select to the trigger to get scope identity
Why do I have to modify my DB or my view to satisfy some hidden M$ assumption?
None the less, after two very frustrating days, code is now working. Maybe this will save someone else some time as well.
Try this
[HttpPost]
public ActionResult Register(User model)
{
DateTime bla = new DateTime(2012, 12, 12);
try
{
model.gid = 1;
model.cid = 1;
model.creationDate = bla;
model.active = 1;
myContext.Users.AddObject(model);
myContext.SaveChanges();
}
catch (Exception ex)
{
Console.WriteLine(ex);
throw;
}
return View();
}
I was having this issue and my fix, was that in my connection-string metadata I did not specify my model in the .msl format.
See more info here
In my case, SetName of the entity was incorrect. Shortly, this worked for me:
Use
myContext.AddObject(nameOfSetEntity, user);
Instead of:
myContext.Users.AddObject(user);
To get the whole correct name of the entity (thanks to Nix's answer)
string className = typeof(User).Name;
var container = myContext.MetadataWorkspace.GetEntityContainer(myContext.DefaultContainerName, System.Data.Metadata.Edm.DataSpace.CSpace);
string nameOfSetEntity= (from meta in container.BaseEntitySets
where meta.ElementType.Name == className
select meta.Name).First();
Context.AddObject(nameOfSetEntity, user);

Resources