2017-04-07 7 views
1

グリッドビューとSQLDataSourceコントロールを使用してアプリケーション内のショッピングカートを更新しようとしていますが、SQLストアドプロシージャに値を送信できるように更新コマンドパラメータを設定しようとしています。しかし、それはnvarcharからstringに変換できないという例外をスローし続けます。UpdateCommandパラメータ値は常に文字列

以下のコードを与えます。

ProductsDataSource.UpdateParameters.Add("Description", row.Cells[2].Text); 

第二引数だとして、この方法は、文字列以外は受け付けませんので、どのように私は私のパラメータに渡すために他の値にそれを変換できるようですか?

私はすでにこのようなことを試みました。

int productID = int.Parse(row.Cells[1].Text); 

が、その2番目のパラメータは文字列引数を持つようにしているので、私は(それが暗黙的に文字列に変換することはできません不満!)私のDBに挿入することはできません

+0

なぜ最初に 'SqlDataSource'を使用していますか?どうして普通のADO.NETに固執せず、 'SqlConnection'と' SqlCommand'を使うのですか? – mason

+0

'SqlDataSource'を使うのは本当に意味がありません!これで、データベースコードをUIレイヤーに振りかけることができました。それは良いことではありません!代わりに、データベース操作を別々のクラス(別々のクラスライブラリに配置されることが多い)にカプセル化し、ページがそのクラスのインスタンスを取得してデータベースとのやりとりを実行する必要があります。あなたは "リポジトリパターン"を調べるべきです。 – mason

+0

UpdateParameters.Addで型を指定できる別のオーバーロードはありますか( – McGaz

答えて

1

..

<UpdateParameters > 
    <asp:Parameter Name="paramName" DbType="String" Type="String" /> 

、あなたが背後にあるコードの値を設定することができます。

または、マークアップ定義なしでAddメソッドのオーバーロードを使用できます。

SqlDataSource1.UpdateParameters.Add("paramName", DbType.String, "parameter value"); 
-3

(= 文字列のproductIDをお試しください文字列)(row.Cells [1]。テキスト)

+2

)文字列への文字列のキャスト –

+0

デバッガでの返り値return row.Cells [1] .Text返された文字列を文字列に変換する必要がない場合それ以外の場合は、文字列 – LaFleur

2

コードが機能しない理由に直接答えるのではなく、私は別の方法を提示すると思いました。 SqlDataSourceでエラーを修正したとしても、長期的には引き続き使用することは悪いと思います。 WebページのコントロールとしてSqlDataSourceを使用すると、UIレイヤーにデータベースコードが振りかざされます。これは非常に厄介であり、現代のアプリケーションではそれを回避しようとしています。 SqlDataSourceは、厳密に型指定されたモデルオブジェクトを使用する代わりにマジック文字列を推奨します。

SqlDataSourceを完全に捨て、直接(おそらくDapperのようないくつかのmicro-ORMを通して)ADO.NETを直接使用することです。また、このロジックを独自のクラスに移して、リポジトリパターンに従うこともできます。そのクラスは、アプリケーションが次に参照する別のクラスライブラリに配置するのが最善です。次に、そのクラスを他のアプリケーションから再利用できます。私は個人的にコンソールアプリケーションを持っているので、ウェブサイトを経由することなくリポジトリのビットをテストできます。

あなたのウェブサイトをこのリポジトリクラスに直接依存させるのではなく、インターフェイスを使って作業することがよくあります。これにより、ウェブサイトは、データベースロジックの実装方法に直接依存する必要がなくなります。しばしばこれは依存性注入と結びついていますが、それはこのポストの対象となるには大きすぎます。依存性注入についてthis excellent videoをチェックアウトすることを強くお勧めします。実際の実装のための今すぐ

public interface IProductRepository 
{ 
    Product GetProductById(int id); 

    void UpdateProduct(Product product); 

    List<Product> GetAllProducts(); 
} 

だから、ここで私たちのインターフェースです

:あなたは、既存のものを持っていない場合

public class SqlServerProductRepository: IProductRepository 
{ 
    private readonly string _connectionString; 

    public ProductRepository(string connectionString) 
    { 
     _connectionString = connectionString; 
    } 

    public Product GetProductById(int id) 
    { 
     using(var connection = new SqlConnection(_connectionString)) 
     { 
      //QuerySingle is an extension method from Dapper 
      return connection.QuerySingle<Product>("select Name, Description, Id from Products where Id = @Id", new {Id = id}); 
     } 
    } 

    public void UpdateProduct(Product product) 
    { 
     using(var connection = new SqlConnection(_connectionString)) 
     { 
      //Execute is an extension method from Dapper 
      connection.Execute("update Products set Name = @Name, Description = @Description where Id = @Id", product); 
     } 
    } 

    public List<Product> GetAllProducts() 
    { 
     using(var connection = new SqlConnection(_connectionString)) 
     { 
      //Query is an extension method from Dapper 
      //You'd likely want to implement filters/paging etc in a real world app 
      return connection.Query<Product>("select Name, Description, Id from Products").AsList(); 
     } 
    } 
} 

あなたはモデルクラスが必要になります

public class Product 
{ 
    public int Id { get; set; } 

    public string Name { get; set; } 

    public string Description { get; set; } 
} 

あなたのウェブサイトのコードは、はるかに単純になりました。

SaveChangesなどを呼び出すまで一括変更するなど、リポジトリの実装には別の方法がありますが、これは基本的な実装です。

データベースインタラクションをインタフェースの背後で抽象化するもう1つの利点は、ウェブサイト全体を変更することなく、さまざまな実装を試すことができることです。 Entity Frameworkを試したいですか? IProductRepositoryを実装する新しいEntityFrameworkProductRepositoryを作成します。データベースを完全に切り替える場合はどうすればよいですか? SqlLiteは無料で軽量で、小さなアプリケーションに適しています。新しいSqlLiteProductRepositoryを作成します。あなたはマークアップのパラメータの型を指定することができ

+0

に変換する必要がありますありがとう、私はこれを調べる:) –

関連する問題