2016-02-10 4 views
0

У меня, кажется, странная проблема, и я не могу понять, что я делаю неправильно. Мой код должен обновить запись, но это не будет.ADO.NET MSAccess Update терпит неудачу, потому что предложение WHERE с параметрами не попадет

IDbCommand cmd = ((IConnectionProvider) _Tender).Connection.CreateCommand(); 

if(_ID == null) 
{ 
    cmd.CommandText = "INSERT INTO ELEMENTS (ID, HOP, HMODE, HSORT, HFLAGS, KPARENT, TEMPLATE, NUMV, NAMV, TITLE, TXTV, RESERVED, CDATA, VDATA) VALUES (@id, @hop, @hmode, @hsort, @hflags, @kparent, @template, @numv, @namv, @title, @txtv, @reserved, @cdata, @vdata)"; 
    _ID = _CreateID(); 
    _Tender.Factory._Cache.Add(_ID, this); 
} 
else 
{ 
    cmd.CommandText = "UPDATE ELEMENTS SET HOP = @hop, HMODE = @hmode, HSORT = @hsort, HFLAGS = @hflags, KPARENT = @kparent, TEMPLATE = @template, NUMV = @numv, NAMV = @namv, TITLE = @title, TXTV = @txtv, RESERVED = @reserved, CDATA = @cdata, VDATA = @vdata WHERE ID = @id"; 
} 

cmd.AddParameter("@id", _ID); 
cmd.AddParameter("@hop", _ActualType); 
cmd.AddParameter("@hmode", _Mode); 
cmd.AddParameter("@hsort", _Sort); 
cmd.AddParameter("@hflags", _Flags); 
cmd.AddParameter("@kparent", ((_Parent == null) ? "" : _Parent.ID)); 
cmd.AddParameter("@template", ((_Template == null) ? "" : _Template.ToString())); 
cmd.AddParameter("@numv", _Number); 
cmd.AddParameter("@namv", _Name); 
cmd.AddParameter("@title", _Title); 
cmd.AddParameter("@txtv", _Text); 
cmd.AddParameter("@reserved", _Reserved); 
cmd.AddParameter("@cdata", _CData); 
cmd.AddParameter("@vdata", _VData); 

int v = cmd.ExecuteNonQuery(); 

Часть INSERT работает просто отлично. Часть UPDATE не обновляет запись по причинам, которые я не могу понять. v в последнем утверждении 0.

Если я кладу текст команды вроде этого:

cmd.CommandText = "UPDATE ELEMENTS SET HOP = @hop, HMODE = @hmode, HSORT = @hsort, HFLAGS = @hflags, KPARENT = @kparent, TEMPLATE = @template, NUMV = @numv, NAMV = @namv, TITLE = @title, TXTV = @txtv, RESERVED = @reserved, CDATA = @cdata, VDATA = @vdata WHERE ID = '" + _ID + "'"; 

(не используя переменную связывания в ИНЕКЕ) он работает (v == 1).

Я использую интерфейсы для соображений переносимости, для удобства я написал методы расширения AddParameter(). _ID - это буквенно-цифровое значение, например «g5fRRa3P89gX» или что-то в этом роде.

_Connection = new OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + path + ";"); 

public static IDbDataParameter AddParameter(this IDbCommand cmd, string name, DbType type, object value) 
{ 
    IDbDataParameter p = cmd.CreateParameter(); 

    p.DbType = type; 
    p.ParameterName = name; 
    p.Value = value; 

    if(value is string) 
    { 
     p.Size = ((string) value).Length; 
     if(p.Size == 0) { p.Size = 1; } 
    } 
    else 
    { 
     p.Size = sizeof(int); 
    } 

    cmd.Parameters.Add(p); 

    return p; 
} 

public static IDbDataParameter AddParameter(this IDbCommand cmd, string name, string value) 
{ 
    return AddParameter(cmd, name, DbType.String, value); 
} 

public static IDbDataParameter AddParameter(this IDbCommand cmd, string name, int value) 
{ 
    return AddParameter(cmd, name, DbType.Int32, value); 
} 

У кого-нибудь есть идея? Спасибо, Алекс.

ответ

0

Я нашел решение, и это менее неудобно, как я думал. Кажется, драйвер просто не поддерживает с параметрами. Это как-то странно, потому что вы можете их определять и использовать, но, видимо, они всегда будут применяться в том порядке, в котором они были добавлены в команду без учета их имен. Таким образом, код будет работать для части UPDATE, когда последнему назначен параметр @id ...