2015-06-13 3 views
0

Я пытаюсь исправить проблему с дублирующейся записью при создании новой записи с помощью действия Json Create.Повторяющаяся запись в db с Json Создание Action Asp.Net MVC

Json скрипт на мой взгляд

$.ajax({ 
    url:'/Panels/CreateNewAlert', 
    dataType:'json'; 
    type:'post', 
    contentType:'application/json;charset=utf-8' 
    data:JSON.stringify({ 
     alertMap:{AlertModeID:$('#AlertModeID').val(),AlertPriorityID:$('#AlertPriorityID').val()}, 
     alertLog:{AlertTitle:$('#AlertLog_AlertTitle').val(),AlertText:$('#AlertLog_AlertText').val(),AlertStartDate:$('#AlertLog_AlertStartDate').val(),AlertActive:'true'}, 
     recipientlistip:brutelistip, 
     recipientlistpc:brutelistpc 
    }), 
    async:true, 
    processData:false, 
    cache:false, 
    succes:function(data){ 
     alert(data); 
    }, 
    error:function(xhr){ 
     alert('error'); 
    } 
}) 

Контроллер

[HttpPost] 
public JsonResult CreateNewAlert(AlertMap alertMap, AlertLog alertLog, RecipientMap recipientMap, int[] recipientlistip, int[] recipientlistpc) 
{ 
    if(ModelState.IsValid) 
    { 
    db.AlertLog.Add(alertLog); 
    db.SaveChanges(); 

    int alertid = alertLog.AlertID; 
    recipientMap.IPgroupID = 3; 
    recipientMap.AlertID = alertid; 
    db.RecipientMap.Add(recipientMap); 
    db.SaveChanges(); 

    alertMap.AlertID=alertid; 
    alertMap.UsersID= User.Identity.GetUserId(); 
    db.AlertMap.Add(alertMap); 
    db.SaveChanges(); 
    } 
    return Json("Succes!"); 
} 

Я не понимаю, почему alertLog записывается дважды, с двумя различными ид. alertMap и recipientMap записываются без дубликата.

Я проверил с ответом VS и db.SaveChanges() для alertLog, выполняется только один раз. Я пробовал тест:

alertLog.AlertActive = true; 
alertLog.AlertTitle = "pif"; 
alertLog.AlertText = "pof"; 
alertLog.AlertStartDate = DateTime.Now; 
alertLog.AlertEndDate = DateTime.Now; 
db.AlertLog.Add(alertLog); 
db.SaveChanges(); 

Я добавил данные непосредственно в контроллер ... и нет дубликатов. Может быть, мой синтаксис Json, который является неправильным ... Есть ли еще один тест, который я мог бы сделать? Thanks

EDIT: Я думаю, что это проблема с внешним ключом AlertID. AlertID находится в таблице AlertLog, как первичный ключ с приращением идентичности. У меня есть ссылка на AlertID в моей RecipientMap как внешний ключ. Когда пользователь пишет DeskAlert, он выбирает список получателей для этого предупреждения (группа IP или группа pc). Так RecipientMap таблица может нравится:

|ID(Pk)|IPgroupID(fk)|PCgroupID(fk)|AlertID(fk)| 
|------|-------------|-------------|-----------| 
| 1 | 1   | null  | 15  | 
| 2 | 1   | null  | 15  | 
| 3 | 2   | 1   | 16  | 

Я думаю, что моя проблема в том, AlertID внешний ключ не хорошо сконфигурирован

EDIT 2: Ok это последний шаг.

Есть последнее, что я не понимаю. Речь идет о том, как добавить список в мой datatable. Я пытаюсь использовать список, но я что-то пропустил.

var AL = new AlertLog() 
{..}; 
var IPlist = new List<RecipientMap>(); 
var rp = new RecipientMap(); 
foreach (int ipid in recipientlistip) 
{ 
    RM.IPgroupID = ipid; 
} 
IPlist.Add(rp); 
AL.RecipientMap.AddRange(IPlist); 

С последней строке я получаю эту ошибку на AddRange "System.Collections.Generic.ICollection<WebAppDev.RecipientMap> does not contain a definition for 'AddRange' and no extension method 'AddRange' accepting a first argument of type System.Collections.Generic.ICollection<WebAppDev.RecipientMap> could be found (are you missing a using directive or an assembly reference?)"

В моем файле класса модели IPgroupID и PCgroupID являются:

public Nullable<int>IPgroupID {get;set;} 
public Nullable<int>PCgroupID {get;set;} 

И РЕШЕНИЕ! Да Это сработало! В моем контроллере я сделал это (для одного списка):

List<RecipientMap>IPlist= new List<RecipientMap>(); 
for (int i = 0;i<recipientlistip.Length;i++){ 
    IPlist.Add(new RecipientMap 
    { 
     IPgroupID = recipientlistip[i] 
    }); 
} 
AL.RecipientMap.AddRange(IPlist); 

Но я также добавил ExtensionMethods для использования AddRange с ICollection. Вот почему это не сработало с самого начала. Спасибо вам большое за вашу помощь!

+0

Является ли это проблемой в настройке базы данных или сущности? ForeignKeys? Триггеры? Ваша клиентская сторона и код контроллера выглядят отлично. – scgough

ответ

0

Звучит так, что у вас есть один мастер (AlertLog) и две детали (RecipientMap, AlertMap). проверить это, если вы установили отношения в SQL Server:

// create Master 
    var AL = new AlertLog() 
{ AlertModeID = alertLog.AlertModeID, AlertPriorityID = alertLog.AlertPriorityID}; 

    // create Details 
    var RM = new RecipientMap() { .. = ...}; // Do NOT consider FK here! 
    var AM = new AlertMap() { .. = ... }; // Do NOT consider FK here! 

    // add Details to Master 
    AL.RecipentMaps.Add(RM); // FK is automatically set here 
    AL.AlertMaps.Add(AM); // FK is automatically set here 

    db.AlertLog.Add(AL); // add Master 
    db.SaveChanges(); 
+0

Спасибо вам большое. Я пробовал этот образец, и он работает для установки FK автоматически. Но у меня есть еще один вопрос: в таблице RecipientMap, как я могу вставить свой массив ID? например, если мне нужно вставить все ID в int [] recipientlistip с тем же AlertID, как я мог бы это сделать? – mrplume

+0

, вы можете создать «Список » с нужным набором идентификаторов и использовать 'AL.RecipientMaps.AddRange (/ * Список вашей RecipientMap * /)'. Кроме того, если вы установили идентификатор автоматического инкремента для RecipientMap, нет необходимости вообще рассматривать идентификаторы, просто добавьте новые экземпляры в 'List '. @mrplume –

+0

Хорошо, я пробовал это решение, но есть кое-что, что я не понимаю, я сделал редактирование. – mrplume

-1

В некоторых случаях, работающих с JQuery, программисты могут случайно установить два обработчика событий для Submit! проверьте этот вопрос, есть ли у вас «onClick» рядом с вашим обработчиком JQuery или нет?

+0

Я думаю, что это проблема внешнего ключа. В таблице AlertLog AlertID - это уникальный первичный ключ. У меня есть ссылка в RecipientMap для AlertID как внешний ключ. RecipientMap зарегистрированная группа, которая может видеть предупреждение. Таким образом, одна, две или более группы могут быть связаны с одним и тем же AlertID. Этот внешний ключ не должен быть правильно настроен – mrplume

+0

@mrplume просто ваш код звучит нормально, и EF не собирается работать с таким кодом! для записи, попробуйте использовать ONE db.SaveChanges(). также вы можете попробовать что-то еще ... –

0

Прежде всего, убедитесь, что вы используете последнюю EF 6.1.3, во-вторых, вы, возможно, потребуется объединить этот ответ с предыдущим.

Итак, есть List<RecipientMap> нравится следующим образом:

int ipGroupID = // something you know how to find 

var RM1 = new RecipientMap(){IPgroupID = ipGroupID, ..}; 
var RM2 = new RecipientMap(){IPgroupID = ipGroupID, ..}; 
var RM3 = new RecipientMap(){IPgroupID = ipGroupID, ..}; 

var listRM = new List<RecipientMap>(){RM1, RM2, RM3}; 

тогда вместо AL.RecipentMaps.Add(RM) вам нужно AL.RecipentMaps.AddRange(listRM) и сохранить изменения в db. Таким образом, автоматически устанавливается FK AlertLog, а IPgroupID ранее был установлен в список RecipientMap.