You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何以IDataModel为参数并访问具体模型类的属性?

如何通过IDataModel参数访问具体模型类的独有属性?

问题描述

我正在设计一款读写SQL Server数据库的应用,拥有多个对应表记录的模型类。定义了IDataModel接口供这些模型实现,同时定义了包含Update方法签名的IDataStoreUpdatable接口,方法参数为IDataModel。但在实现Update方法时,无法访问模型的独有属性(这些属性未在IDataModel中定义),尝试强制转换为具体类也无效。想请教是否有办法以IDataModel为参数,同时访问实际类的属性?

相关代码:

internal interface IDataModel 
{
    int ID { get; set; }
}

internal interface IDataStoreUpdatable 
{
    void Update(IDataModel model);
    void Update(List<IDataModel> models);
}

public void Update(IDataModel bom)  
{
    transaction = new CommittableTransaction();
    string updateString = $@"UPDATE tblBOMs SET lngPalletSectionID = {bom.PalletSection.ID}, lngQuoteID = {bom.QuoteID}, strComponent = '{bom.Component}',
                                            bytQuantityNeeded = {bom.QuantityNeeded}, sngBDFT = {bom.BoardFeet} WHERE lngBOMID = {bom.ID}";

    OpenConnection();
    _sqlConnection.EnlistTransaction(transaction);
    // ....
}

解决方案

方案一:使用泛型接口约束(推荐)

将IDataStoreUpdatable改成泛型接口,通过泛型约束限定为IDataModel的实现类,这样Update方法可以直接接收具体模型类型,无需转换就能访问独有属性,同时保证类型安全。

示例代码:

// 定义泛型更新接口,约束T为IDataModel的实现类
internal interface IDataStoreUpdatable<T> where T : IDataModel
{
    void Update(T model);
    void Update(List<T> models);
}

// 针对具体模型类(比如BOMModel)实现接口
public class BOMDataStore : IDataStoreUpdatable<BOMModel>
{
    public void Update(BOMModel bom)
    {
        transaction = new CommittableTransaction();
        // 直接访问BOMModel的所有属性
        string updateString = $@"UPDATE tblBOMs SET lngPalletSectionID = {bom.PalletSection.ID}, lngQuoteID = {bom.QuoteID}, strComponent = '{bom.Component}',
                                        bytQuantityNeeded = {bom.QuantityNeeded}, sngBDFT = {bom.BoardFeet} WHERE lngBOMID = {bom.ID}";

        OpenConnection();
        _sqlConnection.EnlistTransaction(transaction);
        // ....
    }

    public void Update(List<BOMModel> models)
    {
        // 批量更新逻辑
    }
}

方案二:安全类型检查与转换(保留非泛型接口时使用)

如果必须保留原有的非泛型接口,可以在Update方法中先判断参数的实际类型,再进行安全转换,避免直接强制转换导致的运行时错误。

示例代码:

public void Update(IDataModel model)
{
    // 用模式匹配安全转换为具体类
    if (model is not BOMModel bom)
    {
        throw new ArgumentException("传入的模型不是BOMModel类型", nameof(model));
    }

    transaction = new CommittableTransaction();
    string updateString = $@"UPDATE tblBOMs SET lngPalletSectionID = {bom.PalletSection.ID}, lngQuoteID = {bom.QuoteID}, strComponent = '{bom.Component}',
                                    bytQuantityNeeded = {bom.QuantityNeeded}, sngBDFT = {bom.BoardFeet} WHERE lngBOMID = {bom.ID}";

    OpenConnection();
    _sqlConnection.EnlistTransaction(transaction);
    // ....
}

额外提醒:避免SQL注入风险

你的代码中直接拼接SQL字符串存在严重的SQL注入风险,建议改用参数化查询:

string updateString = @"UPDATE tblBOMs SET lngPalletSectionID = @PalletSectionID, lngQuoteID = @QuoteID, strComponent = @Component,
                        bytQuantityNeeded = @QuantityNeeded, sngBDFT = @BoardFeet WHERE lngBOMID = @ID";

using var command = new SqlCommand(updateString, _sqlConnection);
command.Parameters.AddWithValue("@PalletSectionID", bom.PalletSection.ID);
command.Parameters.AddWithValue("@QuoteID", bom.QuoteID);
command.Parameters.AddWithValue("@Component", bom.Component);
command.Parameters.AddWithValue("@QuantityNeeded", bom.QuantityNeeded);
command.Parameters.AddWithValue("@BoardFeet", bom.BoardFeet);
command.Parameters.AddWithValue("@ID", bom.ID);

command.ExecuteNonQuery();

内容的提问来源于stack exchange,提问作者James Dorsey

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 21:51:11