代码改变世界

iBATIS.NET Tips & Tricks(1) : 使用Nullable类型

  Anders Cui  阅读(1350)  评论(1编辑  收藏  举报

iBatis中,我们面对的通常会是Domain Model,而不是DataSetDataTable。这样在处理业务逻辑时,就可以不必再关心数据持久相关的东东了。

Domain Model类型的属性常常会对应数据库中表的一个字段(也可能是其它Domain类型的)。比如下面的Product类:

[Serializable]
public partial class Product
{
    
#region private fields

    
private int _productid;

    
private string _productname = String.Empty;
    
private int _categoryid;
    
private string _description = String.Empty;

    
#endregion

    
#region constructors

    public Product() { }

    public Product(int productid)
    {
        
this._productid = productid;
    }

    
#endregion

    
#region Public Properties

    
public int Productid
    {
        
get { return _productid; }
        
set { _productid = value; }
    }


    
public string Productname
    {
        
get { return _productname; }
        
set { _productname = value; }
    }

    
public int CategoryId
    {
        
get { return _categoryid; }
        
set { _categoryid = value; }
    }

    
public string Description
    {
        
get { return _description; }
        
set { _description = value; }
    }

    
#endregion
}

ProductId属性对应表ProductProductId字段,CategoryId对应CategoryId。为了数据的参照完整性,我们可以将CategoryId设置为外键。

这样问题就来了,如果我们通过new Product()的方式新建一个实例,但没有设置CategoryId的值,那么CategoryId的值实际上为int类型的默认值0,这样在插入数据的时候就会发生外键冲突,因为Category表中不存在主键为0的记录。

另外,如果有类型为DateTime的属性,也会有麻烦。DateTime类型的默认值为0001 1 1 日午夜 12:00:00,而这不在SQL Serverdatetime类型的范围内,在插入数据时也会引发错误。难道我们要手工处理所有这些字段?

幸好还有Nullable类型。如果类型的属性为Nullable类型,那么其默认值将为null。从而省却了上面的烦恼。

我们可将Product类的定义改为:

[Serializable]
public partial class Product
{
    
#region private fields

    
private int _productid;

    
private string _productname = String.Empty;
    
private int? _categoryid;
    
private string _description = String.Empty;

    
#endregion

    
#region constructors

    
public Product() { }

    
public Product(int productid)
    {
        
this._productid = productid;
    }

    
#endregion

    
#region Public Properties

    
public int Productid
    {
        
get { return _productid; }
        
set { _productid = value; }
    }


    
public string Productname
    {
        
get { return _productname; }
        
set { _productname = value; }
    }

    
public int? CategoryId
    {
        
get { return _categoryid; }
        
set { _categoryid = value; }
    }

    
public string Description
    {
        
get { return _description; }
        
set { _description = value; }
    }

    
#endregion
}

注意:实际应用中可能不会使用CategoryId,而是使用Category对象作为属性。

编辑推荐:
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
阅读排行:
· 周边上新:园子的第一款马克杯温暖上架
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· DeepSeek如何颠覆传统软件测试?测试工程师会被淘汰吗?
· 使用C#创建一个MCP客户端
点击右上角即可分享
微信分享提示