Is specifying a field name on middle-tier a leaky abstraction?
I feel it is too cumbersome to create a separate function just for each field, even if it is code-generated.
public bool Assortment_IsValueExistingOnOtherRecord( Dictionary<string, object> exceptPkColumns, string field, object value ) { var c = Connect(); var dt = new DataTable(); string sanitizedField = field.Replace(''',''); var daAssortment = new SqlDataAdapter( string.Format( @'SELECT 1 FROM assortment WHERE /* do I violate any good programming practice here? */ [{0}] = @value AND NOT (assortment_id = @assortment_id)', field), c); daAssortment.SelectCommand.Parameters.Add('assortment_id', exceptPkColumns['assortment_id']); daAssortment.SelectCommand.Parameters.Add('value', value); daAssortment.Fill(dt); return dt.Rows.Count == 1; }
From an encapsulation perspective, there is nothing wrong with what you wrote.
However, as ‘David B’ alluded to (he was a little vauge about it), there are some security issues you need to be aware of.
The dynamic SQL you are generating is subject to something called a ‘SQL Injection attack’. Imagine, for example, that the value of field was the following string:
this would result in the database executing 3 queries:
That could, obviously, cause some problems.
If the value of ‘field’ is ever specified via:
Then you need to validate the data to make sure it is a valid field value before running any queries. Otherwise you are vulnerable to attack.