A SQL insert is generated as well as an update when updating - entity-framework-4

I am using Entity Framework 4 self-tracking entities template (STE) and SQL Server CE. I am seeing some very odd behavior. Everything works great if I just insert or update, delete. However if I insert an object and then update it an UPDATE and an INSERT SQL statement will be generated for the object when I perform the update (See below).
I am using a repository pattern and I dispose of the repository and the ObjectContext it wraps for each of the calls so the update uses a new ObjectContext. Also note that if I restart the server the update of the object works fine so it is only the case where I have inserted an object.
The update does the "usual" ApplyChanges and SaveChanges since I am using STE.
The trace for the initial insert is:
Creating ComputerEntities
--=============== BEGIN COMMAND ===============
declare #0 UniqueIdentifier set #0 = '2975bbbb-36a1-4c0a-8075-be273a96cd42'
declare #1 Bit set #1 = 'True'
declare #2 UniqueIdentifier set #2 = '2913bff8-9f2b-4965-8e02-5cb2a98f4498'
declare #3 Int set #3 = '2'
declare #4 Int set #4 = '1'
declare #5 NVarChar set #5 = 'test'
declare #6 NVarChar set #6 = 'C:\ProgramData\Kailana\ReVersion\Repositories\Projects\2975bbbb-36a1-4c0a-8075-be273a96cd42\2975bbbb-36a1-4c0a-8075-be273a96cd42'
insert [Repository]([Id], [Enabled], [ComputerId], [SQLVersionId], [ReleaseId], [Name], [Description], [DataSource], [Password], [DbUser], [DbUserPassword])
values (#0, #1, #2, #3, #4, #5, null, #6, null, null, null)
go
--=============== END COMMAND ===============
Disposing the repository
Disposing the repositories Context.
Next I do an update and this is the SQL that is generated:
Creating ComputerEntities
--=============== BEGIN COMMAND ===============
declare #0 Bit set #0 = 'True'
declare #1 UniqueIdentifier set #1 = '2913bff8-9f2b-4965-8e02-5cb2a98f4498'
declare #2 Int set #2 = '2'
declare #3 Int set #3 = '1'
declare #4 NVarChar set #4 = 'tested'
declare #5 NVarChar set #5 = 'C:\ProgramData\Kailana\ReVersion\Repositories\Projects\2975bbbb-36a1-4c0a-8075-be273a96cd42\2975bbbb-36a1-4c0a-8075-be273a96cd42'
declare #6 UniqueIdentifier set #6 = '2975bbbb-36a1-4c0a-8075-be273a96cd42'
update [Repository]
set [Enabled] = #0, [ComputerId] = #1, [SQLVersionId] = #2, [ReleaseId] = #3, [Name] = #4, [Description] = null, [DataSource] = #5, [Password] = null, [DbUser] = null, [DbUserPassword] = null
where ([Id] = #6)
go
-=============== END COMMAND ===============
--=============== BEGIN COMMAND ===============
declare #0 UniqueIdentifier set #0 = '2975bbbb-36a1-4c0a-8075-be273a96cd42'
declare #1 Bit set #1 = 'True'
declare #2 UniqueIdentifier set #2 = '2913bff8-9f2b-4965-8e02-5cb2a98f4498'
declare #3 Int set #3 = '2'
declare #4 Int set #4 = '1'
declare #5 NVarChar set #5 = 'test'
declare #6 NVarChar set #6 = 'C:\ProgramData\Kailana\ReVersion\Repositories\Projects\2975bbbb-36a1-4c0a-8075-be273a96cd42\2975bbbb-36a1-4c0a-8075-be273a96cd42'
insert [Repository]([Id], [Enabled], [ComputerId], [SQLVersionId], [ReleaseId], [Name], [Description], [DataSource], [Password], [DbUser], [DbUserPassword])
values (#0, #1, #2, #3, #4, #5, null, #6, null, null, null)
go
--=============== END COMMAND ===============
I have exhausted every thought I have on what is causing this so any idea that you have that can get me to look in a new direction is appreciated.
Thanks,
Rick

Try to call AcceptChanges or MarkAsUnchanged on your entity after you successfully inserted it.

Related

db2 Stored Procedure Merge Error

I am trying to create a stored procedure that will run a merge from a staging table to the master table, however, I am getting this error when I try to create:
DB2 SQL Error: SQLCODE=-104, SQLSTATE=42601, SQLERRMC=END-OF-STATEMENT;.LAST_CHANGED_DATE
);<psm_semicolon>, DRIVER=3.69.24 [SQL State=42601, DB Errorcode=-104]
Any help would be appreciated
CREATE PROCEDURE sp_UpdateM25
LANGUAGE SQL
BEGIN
MERGE INTO MEDILOAD.M25 M25
USING ( SELECT NDC_UPC_HR1,
ID_NUM_FORMAT,
REC_CODE,
TRAN_CODE,
OVERLOADED_AREA,
LAST_CHANGED_DATE
FROM MEDILOAD.M25_STAGE) M25_STAGE
on (M25.NDC_UPC_HR1 = M25_STAGE.NDC_UPC_HR1 and M25.REC_CODE = M25_STAGE.REC_CODE)
WHEN matched then
update set
M25.NDC_UPC_HR1 = M25_STAGE.NDC_UPC_HR1,
M25.ID_NUM_FORMAT = M25_STAGE.ID_NUM_FORMAT,
M25.REC_CODE = M25_STAGE.REC_CODE,
M25.TRAN_CODE = M25_STAGE.TRAN_CODE,
M25.OVERLOADED_AREA = M25_STAGE.OVERLOADED_AREA,
M25.LAST_CHANGED_DATE = M25_STAGE.LAST_CHANGED_DATE
WHEN NOT MATCHED then
INSERT
(
M25.NDC_UPC_HR1,
M25.ID_NUM_FORMAT,
M25.REC_CODE,
M25.TRAN_CODE,
M25.OVERLOADED_AREA,
M25.LAST_CHANGED_DATE
)
VALUES
(
M25_STAGE.NDC_UPC_HR1,
M25_STAGE.ID_NUM_FORMAT,
M25_STAGE.REC_CODE,
M25_STAGE.TRAN_CODE,
M25_STAGE.OVERLOADED_AREA,
M25_STAGE.LAST_CHANGED_DATE
);
END
#

Procedure runs,but doesn't do anything

I have a little problem with running a certain procedure in MariaDB.
The funny thing is that when i run the procedure,it doesn't show any errors,but unfortunately it doesn't do anything.
And I can't simply find what's wrong.
Guys please help.Thx
Query:
CREATE DEFINER=`root`#`127.0.0.1` PROCEDURE `p_tun_removal`(IN `GeoTerID` INT)
LANGUAGE SQL
NOT DETERMINISTIC
CONTAINS SQL
SQL SECURITY DEFINER
BEGIN
DECLARE #done INT DEFAULT FALSE;
DECLARE #CurrentVersion INT;
DECLARE #CorrectVersion INT;
DECLARE #BeginVersion INT;
DECLARE cur1
CURSOR FOR
SELECT Distinct(Version)
FROM geo_patch
WHERE TerID = GeoTerID AND Version >= BeginVersion;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
declare exit handler for sqlexception
begin
rollback;
resignal;
end;
CREATE Temporary TABLE `tunnel_temp` (
`ID` INT NOT NULL
)
COLLATE='utf8_general_ci'
ENGINE=InnoDB;
insert into tunnel_temp ( ID ) (
SELECT ID from geo_patch
WHERE Version in ( select Version from geo_patch where Substance = 0 ) and TerID = GeoTerID
);
SET #BeginVersion = ( SELECT Version from geo_patch where ID = ( SELECT ID from tunnel_temp limit 1 ) ) - 1 ;
SET #CorrectVersion = #BeginVersion;
IF (#CorrectVersion < 2) THEN
SET #CorrectVersion = 2;
END IF;
START TRANSACTION;
DELETE FROM geo_patch where ID in ( Select ID from tunnel_temp );
open cur1;
version_loop: LOOP
FETCH cur1 into #CurrentVersion;
IF done THEN
LEAVE version_loop;
END IF;
UPDATE geo_patch SET Version = #CorrectVersion WHERE Version = #CurrentVersion;
SET CorrectVersion = CorrectVersion + 1;
END LOOP;
close cur1;
COMMIT;
UPDATE terrain_blocks SET GeoVersion = ( select Version from geo_patch where TerID = GeoTerID order by Version desc limit 1 ) WHERE ID = GeoTerID;
drop temporary table if exists tunnel_temp;
END
Don't use the construct IN ( SELECT ... ), use a JOIN instead.
Try to avoid cursors by doing the entire operation in a single statement.

SaveChanges not setting value, selecting existing value instead

When trying to commit a modified entry to the database, Entity Framework is selecting values for two properties as opposed to setting them.
The code to commit the entity to the database is as follows:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit(Till till)
{
if (ModelState.IsValid)
{
string username = User.Identity.Name.Substring(User.Identity.Name.LastIndexOf('\\') + 1);
till.ModifiedDate = DateTime.Now;
till.ModifiedByUid_FK = db.Users.Where(m => m.Name.ToLower() == username.ToLower()).First().UserUid_PK;
db.Entry(till).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Index/" + (int)Session["siteid"]);
}
ViewBag.SiteUid_FK = new SelectList(db.Sites, "SiteUid_PK", "Name", till.SiteUid_FK);
ViewBag.ModifiedByUid_FK = new SelectList(db.Users, "UserUid_PK", "EHLogin", till.ModifiedByUid_FK);
ViewBag.CreatedByUid_FK = new SelectList(db.Users, "UserUid_PK", "EHLogin", till.CreatedByUid_FK);
return View(till);
}
When viewed in the profiler, it looks like this:
exec sp_executesql N'update [dbo].[Till]
set [NetworkId] = #0, [MID] = #1, [SiteUid_FK] = #2, [Location] = null, [MasterTillNo] = #3,
[IsMaster] = #4, [IsBackOffice] = #5, [IsCurrent] = #6, [ModifiedByUid_FK] = #7,
[CreatedByUid_FK] = #8, [ProcessFiles] = #9
where ([TillUid_PK] = #10)
select [ModifiedDate], [CreatedDate]
from [dbo].[Till]
where ##ROWCOUNT > 0 and [TillUid_PK] = #10',N'#0 varchar(50),#1 int,#2 int,#3 int,#4 bit,#5 bit,#6
bit,#7 int,#8 int,#9 bit,#10 int',
#0='',#1='',#2=4,#3=42,#4=1,#5=0,#6=1,#7=4,#8=1,#9=1,#10=699
I'm guessing there's some property of the field in the database that EF uses to determine this functionality but I can't figure out what it is. If anyone has any information that'd be fantastic :)
Edit 1
Using Ibrahim's answer below, results in relatively similar SQL:
exec sp_executesql N'declare #p int
update [dbo].[Till]
set #p = 0
where ([TillUid_PK] = #0)
select [ModifiedDate], [CreatedDate]
from [dbo].[Till]
where ##ROWCOUNT > 0 and [TillUid_PK] = #0',N'#0 int',#0=687
This typically happens when properties have the data annotation
[DatabaseGenerated(DatabaseGeneratedOption.Computed)]
or the fluent mapping
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.Computed)
or the StoreGeneratedPattern is Computed in the edmx file.
I'd guess that there is a trigger or a default value on ModifiedDate and CreatedDate on the columns in the database. Maybe it's even useless to set them in your application code.
I have had bad luck with the following also:
db.Entry(entity).State = EntityState.Modified;
So I suggest trying to do the following:
//Get the existing Till
var existingTill = db.Tills.Find(till.TillId);
//Save changes for only changed properties
db.Entry(existingTill).CurrentValues.SetValues(till);
db.SaveChanges();

error line 86 for stored procedure

I am trying to get this stored procedure to work. I have been working for a month straight, was up till 3 last night, and am approaching burnout. I really want to get this to work as we have an ad campaign that we spent hundreds on sending traffic to.
USE [redhotkitties2005db]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[proc_rhkprod_lock_items_for_paypal]
#cfuseridid bigint
,#transaction_guid uniqueidentifier = NULL
AS
BEGIN
SET NOCOUNT ON;
declare #tblcartID bigint
,#cfuserid bigint
,#tblproductsid bigint
,#quantity bigint
,#localInventoryID varchar(100)
,#taxologykey bigint
,#name varchar(1000)
,#shortDescription varchar(8000)
,#productDescription varchar(8000)
,#UorLorUL varchar(2)
,#unitPrice money
,#shippingWeight numeric(6, 2)
,#overSize tinyint
,#smallPic1 nvarchar(100)
,#largePic1 nvarchar(100)
,#smallPic2 nvarchar(100)
,#largePic2 nvarchar(100)
,#smallPic3 nvarchar(100)
,#largePic3 nvarchar(100)
SET #transaction_guid = coalesce(#transaction_guid,newid())
declare c1 cursor forward_only for
select rhkProd_tblCart.tablePK AS tblcartID
,rhkProd_tblProducts.productID as tblproductsid
,rhkProd_tblCart.quantity
,rhkProd_tblProducts.localInventoryID
,rhkProd_tblProducts.name
,rhkProd_tblProducts.taxologyKey
,rhkProd_tblProducts.shortDescription
,rhkProd_tblProducts.productDescription
,rhkProd_tblProducts.UorLorUL
,rhkProd_tblProducts.unitPrice
,rhkProd_tblProducts.shippingWeight
,rhkProd_tblProducts.overSize
,rhkProd_tblProducts.smallPic1
,rhkProd_tblProducts.largePic1
,rhkProd_tblProducts.smallPic2
,rhkProd_tblProducts.largePic2
,rhkProd_tblProducts.smallPic3
,rhkProd_tblProducts.largePic3
from rhkProd_tblCart
INNER JOIN rhkProd_tblProducts
on rhkProd_tblCart.tblProductsFK = rhkProd_tblProducts.productID
where rhkProd_tblCart = #cfuserid
open c1
fetch next
from c1
into #tblcartID
,#cfuserid
,#tblproductsid
,#quantity
,#localinventoryID
,#name
,#taxologykey
,#shortdescription
,#productdescription
,#UorLorUL
,#unitprice
,#shippingweight
,#oversize
,#smallpic1
,#largepic1
,#smallpic2
,#largepic2
,#smallpic3
,#largepic3
begin
while ##fetch_status = 0
insert into rhkprod_tblpaypallock (
,[cfuserid]
,[transaction_guid]
,[timestamp]
,[tblproductsFK]
,[quantity]
,[localInventoryID]
,[name]
,[taxologykey]
,[shortdescription]
,[productdescription]
,[uorlorul]
,[unitprice]
,[shippingweight]
,[oversize]
,[smallpic1]
,[largepic1]
,[smallpic2]
,[largepic2]
,[smallpic3]
,[largepic3]
)
values (
,#cfuserid
,#transaction_guid
,getdate()
,#tblproductsid
,#quantity
,#localinventoryID
,#name
,#taxologykey
,#shortdescription
,#productdescription
,#UorLorUL
,#unitprice
,#shippingweight
,#oversize
,#smallpic1
,#largepic1
,#smallpic2
,#largepic2
,#smallpic3
,#largepic3
)
update rhkprod_tblproducts
set quantity = quantity - #quantity
where productid = #tblproductsid
and UorLorUL in ('U','L')
fetch next
from c1
into #tblcartID
,#cfuserid
,#tblproductsid
,#quantity
,#localinventoryID
,#name
,#taxologykey
,#shortdescription
,#productdescription
,#UorLorUL
,#unitprice
,#shippingweight
,#oversize
,#smallpic1
,#largepic1
,#smallpic2
,#largepic2
,#smallpic3
,#largepic3
close c1
deallocate c1
end
END
Your INSERT statement has a stray comma at the start:
insert into rhkprod_tblpaypallock (
,[cfuserid]
Should be
insert into rhkprod_tblpaypallock (
[cfuserid]
Your VALUES clause also has a stray comma:
values (
,#cfuserid
Should be
values (
#cfuserid

oledb stored procedure c# Procedure or function expects parameter which was not supplied

I am getting the error : Implicit conversion from data type nvarchar to varbinary is not allowed. Use the CONVERT function to run this query.
my c# code snippet is:
OleDbCommand spCmd = new OleDbCommand
("[SomeServer].[dbo].GetAllProperties", conn)
{
CommandType = CommandType.StoredProcedure
};
spCmd.Parameters.AddWithValue("#P1", path);
spCmd.Parameters.AddWithValue("#P5", 4);
int rowsAffected = spCmd.ExecuteNonQuery();
path is a string.
corresponding sql sp is:
ALTER PROCEDURE [dbo].[GetAllProperties]
#P1 nvarchar (425),
#P2 varchar(32) = NULL,
#P3 as varbinary(85) = NULL,
#P4 as nvarchar(260) = NULL,
#P5 int
AS
BEGIN
....
Please let me know how to invoke this sp from c#.
i tried specifying all parameters in order as follows but then i get error: Implicit conversion from data type nvarchar to varbinary is not allowed. Use the CONVERT function to run this query
spCmd.Parameters.AddWithValue("#P1", path);
spCmd.Parameters.AddWithValue("#P2", DBNull.Value);
spCmd.Parameters.AddWithValue("#P3", DBNull.Value);
spCmd.Parameters.AddWithValue("#P4", DBNull.Value);
spCmd.Parameters.AddWithValue("#P5", 4);
int rowsAffected = spCmd.ExecuteNonQuery();
Default parameters are ONLY used when they are not present, in other words do NOT add them to the parameter list.
to pass null values to the optional parameters simply use null instead of DBType.Null. It works:
spCmd.Parameters.AddWithValue("#P1", path);
spCmd.Parameters.AddWithValue("#P2", null);
spCmd.Parameters.AddWithValue("#P3", null);
spCmd.Parameters.AddWithValue("#P4", null);
spCmd.Parameters.AddWithValue("#P5", 24);

Resources