LINQ to SQL DuplicateKeyException проблема - PullRequest
1 голос
/ 15 июля 2009

Я использую LINQ2SQL, и у меня есть таблица «Клиенты» с тремя столбцами

CustmerID, CustomerCode, CustomerName

CustmerID - это первичный ключ (и Identity = yes), а CustomerCode - просто UniqueKey.

Когда я обновляю эту таблицу, используя LINQ to SQL с дублированным кодом клиента, я ожидаю увидеть DuplicateKeyException, но он входит в общий блок исключений вместо блока DuplicateKeyException. Есть идеи?

Это код

публичное обновление void (запрос клиента) { использование (LINQDemoDataContext db = new LINQDemoDataContext ()) { Сущность клиентов = CustomerMapper.ToEntity (новые клиенты (), cust);

            try
            {
                db.Customers.Attach(entity, true);
                db.SubmitChanges();
            }

            //Concurrency Exception
            catch (ChangeConflictException)
            {                               
                throw new ChangeConflictException("A concurrency error occurred!");
            }

            //duplicate record
            catch (DuplicateKeyException)
            {
                throw new DuplicateKeyException(entity.CustmerCode);
            }

            //everything else
            catch (Exception ex)
            {
                throw ex;
            }
        }
    }

Я использую VisualWebDeveloperExpress 2008 и SQL Express 2005.

Спасибо и С уважением, Supremestar

Ответы [ 3 ]

2 голосов
/ 15 июля 2009

Если память служит, и я могу ошибаться, DuplicateKeyException срабатывает только для первичного ключа таблицы.

0 голосов
/ 06 ноября 2012

У меня была проблема при добавлении сущности, полученной из другого DataContext.
(Я связал FooDb-свойство BarDb-Entity с SelectedValue из DropDownList, который имел таблицу из недолговечного DataContext как DataSource)
Давайте посмотрим на внутреннее присоединение (сущность) Linq2Sql:

private void attach_FooDb(FooDb entity){
    this.SendPropertyChanging();
    entity.BarDb = this;
}

И свойство BarDb установлено:

set{
    BarDb previousValue = this._BarDb.Entity;
    if (((previousValue != value) || (this._BarDb.HasLoadedOrAssignedValue == false))){
        this.SendPropertyChanging();
        if ((previousValue != null)){
            this._BarDb.Entity = null;
            previousValue.FooDb.Remove(this);
        }

        this._BarDb.Entity = value;

        if ((value != null)){
            value.FooDb.Add(this);
            this._FK_Bar = value.ID;
        }else{
            this._FK_Bar = default(System.Guid);
        }
        this.SendPropertyChanged("BarDb");
    }
}

Таким образом, при подключении к FooDb соответствующий DataContext распознает объект BarDb как вновь созданный и добавленный, даже если он уже существует в базе данных.

Вы можете решить это:

  • только с использованием одного DataContext или
  • создание свойства BarDb_safe в передающем DataContext, который сначала запрашивает «равный» объект из базы данных, применяет все свойства, а затем присоединяет его обычным способом.
0 голосов
/ 14 июля 2010

Я столкнулся с той же проблемой, когда дублированные ключевые объекты сохранялись в памяти, даже если они не вставлялись в базу данных. Я придумал следующую работу вокруг:

    MyDataContext _myDataContext = new MyDataContext(ConfigurationManager.ConnectionStrings["MyConnectionString"].ConnectionString);

    public void AddObject(object myObject)
    {
        try
        {
            _myDataContext.Objects.InsertOnSubmit(myObject);
            _myDataContext.SubmitChanges();
        }
        catch (System.Data.Linq.DuplicateKeyException ex)
        {
            _myDataContext = new MyDataContext(ConfigurationManager.ConnectionStrings["MyConnectionString"].ConnectionString);
            throw ex;

Затем вы можете перехватить и обработать (или проигнорировать) выброшенное исключение DuplicateKeyException в вызывающей стороне.

Другая работа (хотя и неэффективная и нехватка памяти) заключается в создании нового контекста данных внутри метода AddObject вместо использования общего контекста данных, созданного в качестве члена класса.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...