I want to use EF code first to connect my model classes to my database, for example:
public partial class Header
{
public int Id { get; set; }
public int DeviceId { get; set; }
...
}
and in my DbContext
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Header>().HasKey(k => new { k.Id, k.DeviceId });
modelBuilder.Entity<Header>().MapToStoredProcedures(s =>
{
s.Update(u => u.HasName("dbo.SpUpdateHeader"));
s.Insert(i =>
i.HasName("dbo.SpInsertHeader")
.Result<int>(r => r.Id, "Id"));
s.Delete(d => d.HasName("dbo.SpDeleteHeader"));
});
}
The DeviceId is fixed to the device that the record is generated, and the Id is the identity generated on that device. This DbContext is used to sync all the devices data on the server.
The problem with this code is that on insert, i get this error: A result binding for the property 'Id' was not found on the modification function 'SpInsertHeader'. Ensure that the property is database generated.
And if i set [DatabaseGenerated(DatabaseGeneratedOption.Computed)] attribute or [DatabaseGenerated(DatabaseGeneratedOption.Identity)] that property is never sent to the stored procedure
What can i do to enable this scenario?
EDIT
PROCEDURE [dbo].[SpInsertHeader]
@Id INT,
@DeviceId INT
AS
BEGIN
--get new id
IF(COALESCE(@Id, 0) = 0)
BEGIN
SELECT TOP 1 @Id = COALESCE(h.Id, 0) + 1
FROM Header h
WHERE h.DeviceId = @DeviceId
ORDER BY h.Id DESC;
END
IF(COALESCE(@Id, 0) = 0)
BEGIN
SET @Id = 1;
END
INSERT INTO Header(Id, DeviceId) VALUES (@Id, @DeviceId);
SELECT @Id AS 'Id';
END
SpInsertHeadershould return the generated identity value named asId. - Gert ArnoldIdis not db-generated (you already said so, in retrospect...). I assume it's properly mapped as primary key? I think you shouldn't return anything from the sproc (but I'm not doing this very often). - Gert ArnoldSaveChanges. - Gert Arnold