简体   繁体   English

处理DBNull的通用方法

[英]Generic way of handling DBNull

I have a lot of this type of logic in my code when using the SqlDataReader Is there a cleaner more generic way to handle this? 使用SqlDataReader时,我的代码中有很多这种类型的逻辑。是否有更干净的更通用的方式来处理此问题?

 if (reader["VisitingAddressId"] != DBNull.Value)
 {
     visitingAddress = new Address()
     {
         AddressId = Convert.ToInt64(reader["VisitingAddressId"]),
         Address1 = reader["VisitingAddress"].ToString(),
         AddressType = AddressType.VisitingAddress,
         PostalCode = reader["VisitingPostal"].ToString(),
         PostalDistrict = reader["VisitingPostalDistrict"].ToString()
      };
  }

 if (reader["PostalAddressId"] != DBNull.Value)
 {
     postalAddress = new Address()
     {
         AddressId = Convert.ToInt64(reader["PostalAddressId"]),
         Address1 = reader["PostalAddress"].ToString(),
         AddressType = AddressType.PostalAddress,
         PostalCode = reader["PostalPostal"].ToString(),
         PostalDistrict = reader["PostalPostalDistrict"].ToString()
      };
  }

I have these helper methods in a data service class (you could make them both static): 我在数据服务类中有这些帮助器方法(可以将它们都设置为静态):

    public T CastDBValue<T>(object value)
    {
        return MapValue<T>(value);
    }   

    internal static T MapValue<T>(object value)
    {
        try
        {
            T result;
            result = value == DBNull.Value ? default(T) : (T)value;
            return result;
        }
        catch (InvalidCastException cex)
        {
            logger.ErrorFormat("Invalid cast while mapping db value '{0}' to type {1}. Error: {2}", value, typeof(T).Name, cex);
            throw new InvalidCastException(string.Format("Invalid cast while mapping db value '{0}' to type {1}. Error: {2}", value, typeof(T).Name, cex.Message));
        }
    }

Then in your mapping code, you just do: 然后,在您的映射代码中,您只需执行以下操作:

AddressId = dataService.CastDBValue<int>(reader["AddressId"]));
if (AddressId > 0) { ... }

You could use a micro-ORM like Dapper: http://code.google.com/p/dapper-dot-net/ 您可以使用像Dapper这样的微型ORM: http : //code.google.com/p/dapper-dot-net/

The multi mapping functionality would eliminate all that boiler plate code. 多重映射功能将消除所有样板代码。

db.Query<Post,Address,Address,Post>("select * from Posts left join Address ... etc", 
 (post,vaddress,paddress) => 
  {
     post.VisitingAddress = vaddress; 
     post.PostalAddress = paddress; 
     return post; 
   });

What you are referring to are ORMs, of which there are many. 您所指的是ORM,其中有很多。 NHibernate, Entity Framework, even ADO.NET (which you are already using) has support for relational datasets, although in that case you usually have to use a DataSet or derived, strongly-typed classes. NHibernate,Entity Framework甚至ADO.NET(您已经在使用)都支持关系数据集,尽管在这种情况下,您通常必须使用DataSet或派生的强类型类。

Check out the .NET section here for a list: 在此处查看.NET部分以获取列表:

http://en.wikipedia.org/wiki/List_of_object-relational_mapping_software http://en.wikipedia.org/wiki/List_of_object-relational_mapping_software

What are you requirements? 你有什么要求 Maybe we can narrow it down. 也许我们可以缩小范围。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM