2016-06-18 2 views
0

Я хочу использовать код EF первым соединить мои классы модели в моей базе данных, например:Entity Framework код первой карты хранимых процедур с составными первичными ключами

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 привязано к устройству, которое генерирует запись, а идентификатор - это идентификатор, сгенерированный на этом устройстве. Этот DbContext используется для синхронизации всех данных устройств на сервере.

Проблема с этим кодом заключается в том, что при вставке я получаю эту ошибку: Связывание с результатом для свойства «Id» не было найдено в функции модификации «SpInsertHeader». Убедитесь, что свойство создано в базе данных.

И если я установить [DatabaseGenerated (DatabaseGeneratedOption.Computed)] атрибут или [DatabaseGenerated (DatabaseGeneratedOption.Identity)], что собственность никогда не передается хранимой процедуре

Что я могу сделать, чтобы включить этот сценарий?

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 
+0

'SpInsertHeader' должен возвращать значение, сгенерированное тождественное с именем как' Id'. –

+0

См. Мое редактирование, я забыл фактический SP –

+0

ОК, поэтому 'Id' не создан db (вы уже так сказали, ретроспективно ...). Я предполагаю, что он правильно отображен как первичный ключ? Я думаю, вы не должны возвращать что-либо из sproc (но я не делаю этого очень часто). –

ответ

0

После долгих испытаний и прибегая к помощи, я нашел this blog post с помощью меня нашел решение моей проблемы. Я понимаю, что я не могу получить идентификатор, сгенерированный с помощью базы данных, на созданных сервером объектах и ​​сгенерированный приложением идентификатор, для разных устройств с одним и тем же DbContext.

Так я нужен способ, чтобы иметь 2 Diferent модели отображений, поэтому я создал свойство UseApiModel на моем DbContext и методе OnModelCreating я установить

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 отправит свойство Id или нет в зависимости от DatabaseGeneratedOption.

Я также использую советование Colin Angus Mackay, чтобы сгенерировать Id на ВМЕСТО ВСТАВКА

Смежные вопросы