实体框架代码首先使用复合主键映射存储过程

时间:2016-06-18 22:40:48

标签: c# sql-server entity-framework ef-code-first

我想首先使用EF代码将我的模型类连接到我的数据库,例如:

public partial class Header
{
    public int Id { get; set; }

    public int DeviceId { get; set; }
    ...
}

和我的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"));
     });
}

DeviceId固定为生成记录的设备,Id是在该设备上生成的标识。 此DbContext用于同步服务器上的所有设备数据。

此代码的问题是在插入时,我收到此错误: 在修改函数'SpInsertHeader'上找不到属性'Id'的结果绑定。确保该属性是数据库生成的。

如果我设置[DatabaseGenerated(DatabaseGeneratedOption.Computed)]属性或[DatabaseGenerated(DatabaseGeneratedOption.Identity)],该属性永远不会发送到存储过程

如何启用此方案?

修改

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

1 个答案:

答案 0 :(得分:0)

经过大量测试和谷歌搜索,我发现this blog post帮我找到了解决问题的方法。 我意识到,对于具有相同DbContext的不同设备,我无法在服务器创建的对象和应用程序生成的id上获取数据库生成的id。

所以我需要一种方法来进行2个不同的模型映射,所以我在我的DbContext和OnModelCreating方法上创建了一个UseApiModel属性我设置

modelBuilder.Entity<Header>().Property(t => t.Id)
            .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);

s.Insert(i => i.HasName("dbo.SpInsertHeader").Result<int>(r => r.Id, "Id"));

modelBuilder.Entity<Header>().Property(t => t.Id)
            .HasDatabaseGeneratedOption(DatabaseGeneratedOption.None);

s.Insert(i => i.HasName("dbo.SpApiInsertHeader"));

取决于UseApiModel属性。

Api SP期望有效的Id密钥而另一个SP将生成一个,我需要两个SP,因为EF将根据DatabaseGeneratedOption发送Id属性。

我也使用Colin Angus Mackay建议在INSTEAD OF INSERT上生成Id