为什么此代码无法保留数据?

时间:2012-08-29 15:21:55

标签: ado.net c#-2.0

public class Customer : BaseClass<Customer>
{   
    public string Name { get; set; }
    public DateTime? DateOfBirth { get; set; }
    public string TelephoneNumber { get; set; }
    public string InsuranceProvider { get; set; }
    public int? PolicyNumber { get; set; }
    public byte [] Photo { get; set; }
}

此消息显示:

enter image description here

或者,这个:

enter image description here

如何修改此代码以便能够保留数据?

CustomerDAO.cs

class CustomerDAO
{
    .....
    public int Save(ITransactionManager tm, Customer item)
    {
        int count = -1;

        try
        {
            ISqlQueryExecutor<Customer> queryExecutor = new SqlQueryExecutor<Customer>(tm);

            count = 
                queryExecutor.
                ExecuteNonQuery(@"INSERT INTO Customer(
                                       ID
                                      ,Name
                                      ,TelephoneNumber
                                      ,DateOfBirth,
                                       InsuranceProvider,
                                       PolicyNumber)
                                  VALUES(
                                       @ID
                                      ,@Name
                                      ,@TelephoneNumber
                                      ,@DateOfBirth,
                                       @InsuranceProvider,
                                       @PolicyNumber)",
                                      item.ID,
                                      item.Name,
                                      item.TelephoneNumber,
                                      item.DateOfBirth,
                                      item.InsuranceProvider,
                                      item.PolicyNumber,item.Photo
                                      );
                                  //new DbParameter(item.ID, DbType.Int32),
                                  //new DbParameter(item.Name, DbType.String),
                                  //new DbParameter(item.TelephoneNumber, DbType.String),
                                  //new DbParameter(item.DateOfBirth, DbType.DateTime),
                                  //new DbParameter(item.InsuranceProvider, DbType.String),
                                  //new DbParameter(item.PolicyNumber, DbType.Int32)
                                  //new DbParameter(item.Photo, DbType.Binary)
                                  //);



            string str = string.Empty;
        }
        catch (Exception ex)
        {
            throw ex;
        }

        return count;
    }
    .... ....
}

CustomerBLL.cs

class CustomerBLL
{
... ... ...
    public int Save(Customer item)
    {
        int newId = 0;

        ITransactionManager tm = ApplicationContext.Get(DBNameConst.ActiveConnStringName);

        try
        {
            tm.BeginTransaction();

            item.ID = newId = PivotTable.GetNextID(tm, "Customer").Value;

            customerDao.Save(tm, item);

            PivotTable.UpdateNextIdField(tm, "Customer", newId);

            tm.CommitTransaction();
        }
        catch (Exception ex)
        {
            tm.RollbackTransaction();

            throw ex;
        }

        return newId;
    }
    ... ... ...
 }

ASqlQueryExecutor.cs

public abstract class ASqlQueryExecutor<T> : ISqlQueryExecutor<T>
{
 public virtual int ExecuteNonQuery(string queryString, params object[] parameters)
    {
        int count = -1;

        try
        {
            Command = ParameterAttacher.AttachSaveParameters(TransactionManager, queryString, parameters);
            Command.CommandText = queryString;
            count = Command.ExecuteNonQuery();
        }
        catch (Exception ex)
        {
            throw ex;
        }

        return count;
    }      

ParameterAttacher.cs

class ParameterAttacher
{
    public static IDbCommand AttachSaveParameters(ITransactionManager tm, string queryString, params object [] argumentsList)
    {
        IDbCommand command = new DbObjectInstantiator(tm.ProviderName).CreateCommand();
        command.Connection = tm.Connection;
        command.Transaction = tm.Transaction;

        IList<string> parameterNamesList = new List<string>(ParameterParser.Parse(queryString));

        if (parameterNamesList.Count > 0 && argumentsList.Length == argumentsList.Length)
        {
            int i = 0;

            foreach (string paramName in parameterNamesList)
            {
                Attach(command, paramName, argumentsList[i]);

                ++i;
            }
        }

        return command;
    }

    public static void Attach(IDbCommand command, string paramName, object dbParam)
    {
        IDbDataParameter param = command.CreateParameter();

        param.ParameterName = paramName;
        param.Value = (dbParam==null) ? ((object)DBNull.Value) : dbParam;
        //param.DbType = dbParam.DbType;

        command.Parameters.Add(param);
    }
}

enter image description here

1 个答案:

答案 0 :(得分:3)

  

字符串或二进制数据将被截断。声明已被终止

这可能是因为您尝试将过多数据存储到列中。例如,如果数据库中有nvarchar(5)列,并且您尝试在其中存储“this is a string”,则可能会出现该错误,因为5个字符无法保存所有“this is a string”。

您可以通过将UI中的字段限制为与数据库中的字段相同的长度来避免此问题。或者,您可以检查验证方法。

  

不允许从数据类型nvarchar到二进制的隐式转换。

这似乎相当明显:您正在尝试将字符值存储在二进制列中。您还没有提供数据库架构,所以我无法确定它的位置;但是,如果数据库中的列或sproc参数设置为binary,但您的C#将其详细信息为DbType.String,则可能会出现此错误。

更新

您从未在DbType中设置ParameterAttacher.Attach。这意味着参数类型的Parameter默认为DbType.AnsiString。如果你传递它byte[]可能将其转换为ansi字符串,但是当参数被赋予ADO时,它将看到 DbType.AnsiString 并进行比较那个varbinary(50)(或money,或datetime,或int等)并抛出一个例外,详细说明它不知道如何转换为{{1 (例如隐式转换)。

另外,帮自己一个忙,摆脱:

binary

这只会迫使你放弃异常的真实位置,导致你浪费时间去弄清楚真正的问题所在。

当您必须捕获时(例如,当您想要回滚交易时,只需catch(Exception ex) { throw ex; } ,请不要throw。只有throw ex不会丢失堆栈信息,您可以跟踪在异常的位置。例如:

throw