2014-02-16 5 views
0

я пытался несколько вещей:Как устранить нарушение основного ключа Framework Entity Framework на INSERT?

  1. Прикрепление данных в контексте
  2. вручную изменения EDMX файла (здесь это source)
  3. вручную получать ForeignKey объекта с (data.RTMS_GsmOperator = Context.RTMS_GsmOperator.FirstOrDefault(c => c.Id == data.GsmOperatorId);), а затем SaveChanges

Вот код для варианта 1:

 data.Id = GetMaxId(data) 
    Context.Attach(data); //Here I attached it 
    Context.RTMS_PackageApplication.AddObject(data); 
    Context.SaveChanges(); //I get the error here 

Вот код Вариант 3:

data.Id = GetMaxId (данные)

data.RTMS_GsmOperator = Context.RTMS_GsmOperator.FirstOrDefault(c => c.Id == data.GsmOperatorId); //Here 
data.RTMS_Machine = Context.RTMS_Machine.FirstOrDefault(c => c.Id == data.MachineId); //Here 

Context.RTMS_PackageApplication.AddObject(data); 
Context.SaveChanges(); //I get the error here 

None выше работал!

enter image description here

Примечание: Ни один из идентификаторов не автоинкрементный.

Когда я запускаю код ниже:

public RTMS_PackageApplication Insert(RTMS_PackageApplication data) 
{ 
    using (var Context = base.RtmsEntites) 
    { 
     //Since, its not auto-incremental, I do it manually. 
     data.Id = GetMaxId(data) 
     Context.RTMS_PackageApplication.AddObject(data); 
     Context.SaveChanges(); //I get the error here 
    } 
} 

Ошибка:

Violation of PRIMARY KEY constraint 'PK_GsmOperator'. Cannot insert duplicate key in object 'dbo.RTMS_GsmOperator'. The duplicate key value is (1). 
The statement has been terminated. 

Если вы должны знать, вот GetMaxId метод:

private int GetMaxId(RTMS_PackageApplication data) 
{ 
int Result = 1; 
var Temp = 
         base.RtmsEntites.RTMS_PackageApplication.AsQueryable().OrderByDescending(u => u.Id). 
          FirstOrDefault(); 
        if (Temp != null) 
         Result = Temp.Id + 1; 

return Result; 
} 

Что касается ауто- инкрементальный; проблема находится на GsmOperatorId (таблица данных внешнего ключа), и данные УЖЕ там, я просто хочу добавить Id в таблицу PackageApplciation. Таким образом, я НЕ пытается добавить новый GsmOperator только PackageApplication

ЭФ пытается ВСТАВИТЬ GsmOperator и Machine объектов, а также. Но почему? Я даже повторил его, как в одном из ответов ниже.

Как это исправить?

+0

Вариант 1 или 3 должен быть успешным. Можете ли вы показать полный код, как вы пробовали эти два решения? – Slauma

+0

Я добавил код в свой вопрос. –

+0

Как вы управляете временем жизни контекста 'base.RtmsEntites'? По-видимому, вы не создаете новый в блоке 'using', а используете существующий. (Это выражение 'using' очень * странно.) По какой-то причине объект' data.RTMS_GsmOperator' находится в состоянии 'Added', и это могло произойти намного раньше, если у вас есть контекст с большим сроком службы. – Slauma

ответ

0

Хорошо, я узнал, что я сделал небольшую ошибку, и благодаря Elio.Batista я понял, что это.

Для целей проверки я установил некоторые значения по умолчанию для некоторых свойств. Среди этих свойств есть GsmOperator и Machine.

Но вместо того, чтобы устанавливать свойство GsmOperatorId, я ошибочно установил свойство RTMS_GsmOperator, которое является объектом E-F. И поскольку я установил какое-то значение по умолчанию, его значение не равно null, а E-F распознает его как объект NEW и пытается выполнить его INSERT.

Таким образом, в течение EF INSERT объекты, связанные с объектом ForeignKey, должны иметь значение NULL.

Мой неправильно код:

//Notice that this is partial entity class of EF edmx file 
public partial class RTMS_PackageApplication 
{ 
    public RTMS_PackageApplication() 
    { 
     this.RTMS_GsmOperator = new RTMS_GsmOperator(); 
     this.RTMS_Machine = new RTMS_Machine(); 
    } 
} 

Теперь я изменил и исправил на:

//Notice that this is partial entity class of EF edmx file 
public partial class RTMS_PackageApplication 
{ 
    public RTMS_PackageApplication() 
    { 
     this.GsmOperatorId = 0; //As Default value 
     this.MachineId = 0; //As Default value 
    } 
} 
0

Я думаю, что правильное решение здесь состоит в том, чтобы сделать поле автоинкрементным полем id, вместо того, чтобы пытаться вымыть его самостоятельно.

Даже если вам удастся преодолеть эту ошибку, что происходит при увеличении нагрузки, а несколько клиентов одновременно вставляют записи? - у вас могут возникнуть конфликты, т. е. двум другим клиентам говорят, что следующий «maxId» - это то же самое число ... Пусть сервер БД справляется с этим для вас ... вот в чем его преимущество.

+0

Проблема в GsmOperatorId, и данные УЖЕ там, я просто хочу добавить Id в таблицу PackageApplciation. Итак, я НЕ пытаюсь добавить только новый GsmOperator PackageApplication –

+0

И для записи: я попытался сделать PackageApplication автоматически инкрементальным и обновил мою модель на стороне .net, но не работал. Еще одна ошибка! –

1

Можете ли вы попытаться сохранить изменения, используя тот же экземпляр DataContext, который используется для загрузки RTMS_GsmOperator? Что-то вроде этого:

var opr = theContext.RTMS_GsmOperator.FirstOrDefault(c => c.Id == WHATEVER); 
var pa = new RTMS_PackageApplication(); 
pa.RTMS_GsmOperator = opr; 
pa.RTMS_Machine= <RTMS_Machine_Variable> ; 
opr.RTMS_PackageApplications.Add(pa); 
theContext.SaveChanges(); 
+0

Очень здравый подход. Но WTH ошибается в EF? I событие DETACHED Gsm и машина сначала, а затем снова подключили его, все еще не работая. И также попробовал JUST присоединить эти 2 объекта без отсоединения. Еще ничего хорошего. –

+0

Как я вижу, вы загружаете эти экземпляры в один контекст и используете его в другом экземпляре контекста. Какая base.RtmsEntites выглядит? –

+0

Фактически это НЕ ранее созданный экземпляр. 'base.RtmsEntities' всегда new(). Пример: «новые RTMSEntities (Utility.ConnectionStrings.RtmsEntities)» Единственная причина, по которой я это делал, чтобы уменьшить код и более управляемый, просто покончить позже, мне нужно что-то еще, я добавил свойство, которое всегда возвращается как NEW –

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