Coding style 这是一个漏洞百出的抽象吗?

Coding style 这是一个漏洞百出的抽象吗?,coding-style,Coding Style,在中间层指定字段名是一个泄漏的抽象吗 我觉得为每个字段创建单独的函数太麻烦了,即使它是代码生成的 public bool Assortment_IsValueExistingOnOtherRecord( Dictionary<string, object> exceptPkColumns, string field, object value ) { var

在中间层指定字段名是一个泄漏的抽象吗

我觉得为每个字段创建单独的函数太麻烦了,即使它是代码生成的

        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;
        } 
只要采取适当的措施,这是可以的。卫生处理不在这些措施之列

选项1:你是否与该领域的提供者有默契的信任,这样你就知道他们永远不会和你捣乱?例如,如果您作为本模块的作者是字段的提供者,您可以信任自己

选项2:是否可以进行枚举/查找,将请求的字段映射到字符串?然后,此代码的客户端只能请求枚举中的内容,而您这个模块的作者通过将其请求的枚举值映射到已知字符串,成为字段提供程序

选项3:如果字段随时间变化,并且您不想锁定枚举,您可以将字符串值发送到数据库中进行确认吗

SELECT name
FROM syscolumns
WHERE name = @name

这会将提供的名称映射到来自数据库的已知字符串,该字符串必须是安全的。

从封装的角度来看,您编写的内容没有问题

然而,正如David B所暗示的,他对此有点吹牛,有一些安全问题需要注意

您正在生成的动态SQL受到所谓的SQL注入攻击。例如,假设field的值为以下字符串:

assortment_id] = 0 and assortment_id = 1 
delete from assortment
select 1 from assortment where [assortment_id
这将导致数据库执行3个查询:

未返回任何结果的伪select查询 删除组合表中所有内容的删除查询 一个真正的select查询 显然,这可能会导致一些问题

如果通过以下方式指定字段值:

用户界面字段 网页表单提交 从web服务客户端 从磁盘上的文件加载 或者以除您在代码中提供的常量值以外的任何方式
然后,在运行任何查询之前,您需要验证数据以确保它是有效的字段值。否则您容易受到攻击。

使用表达式,您将拥有编译时和Sql运行时安全性:

public bool Assortment_IsValueExistingOnOtherRecord<TValue>(
        Dictionary<string, object> exceptPks,
        Expression<Func<Assortment, TValue>> expression,
        TValue value
        )

    propExp = expression.Body as MemberExpression;
    if (propExp == null) throw new ArgumentException();
    string field = propExp.Member.Name; 

    /* blah, blah */
}

/* Calling code */
bool exists = Assortment_IsValueExistingOnOtherRecord(
                exceptPKs, 
                (a => a.Property1),
                "property1Value"
              );
使用泛型TValue,您还可以得到一个与属性匹配的强类型值,从而避免RDBMS为您所做的偶尔的脑死亡转换

您可以使用整个equals表达式,甚至可以添加对<和>-的支持,但是,这样您就可以将LINQ发明为自己开发的ORM了


顺便说一句,exceptPKs似乎有点奇怪……但也许在上下文中它是有意义的?

是的。所有的抽象都会泄漏


现在,为了安全起见,如果您不明确相信所有呼叫者不会偷懒或试图主动攻击您,您最好有一个包含所有可能字段的emum,并根据该列表验证传入参数。

您是否考虑过使用ORM或数据访问层DAL?即使我使用ORM或DAL,我想我会回到原点的。i、 e.不知道良好编程的实践/基础您将字段净化为sanitizedField,但在string.Format调用中使用了原始的未初始化字段。@Mark:一个好的地方,如果程序员忽略了这些类型的内容,肯定会对程序造成不良影响/我正在考虑如何平衡实用性和健壮性。例如,对于ExceptPK,如果我打开一个现有记录,然后检查即将修改的记录的描述符或任何其他字段是否会与现有记录的描述符或字段冲突,程序应该豁免打开的记录,即使用打开的记录的pkhmm。。远程处理/Webservices可以封送程序的代码吗?我以为他们只能传输数据。如果那样的话,也许我需要试试works@Haore:exceptPKs-为什么它是一本字典?如果您拥有完整的对象,则看起来像一个列表;如果您只有ID,则更适合这种情况。此外,您的SQL字符串将只使用=比较,但看起来您可以使用多个PK。正如我希望使用单字段代理主键设计我的数据库一样,其他db设计器可能会使用复合主键设计他们的db。我的代码生成器应该允许这样做,因此字段字典就是这样。复合pk可以是不同字段类型的组合。
public bool Assortment_IsValueExistingOnOtherRecord<TValue>(
        Dictionary<string, object> exceptPks,
        Expression<Func<Assortment, TValue>> expression,
        TValue value
        )

    propExp = expression.Body as MemberExpression;
    if (propExp == null) throw new ArgumentException();
    string field = propExp.Member.Name; 

    /* blah, blah */
}

/* Calling code */
bool exists = Assortment_IsValueExistingOnOtherRecord(
                exceptPKs, 
                (a => a.Property1),
                "property1Value"
              );