- 浏览: 475033 次
- 性别:
- 来自: 北京
文章分类
- 全部博客 (1028)
- [发布至博客园首页] (826)
- [随笔分类]个人生活随笔 (14)
- [网站分类]首页候选区 (26)
- [网站分类]SharePoint (15)
- [网站分类]其他技术区 (6)
- [随笔分类]批处理技巧 (6)
- [随笔分类].net 2.0 (3)
- [随笔分类]SharePoint2007(MOSS2007) (0)
- [网站分类].NET新手区 (6)
- [网站分类]ASP.NET (6)
- [网站分类]架构设计 (18)
- [网站分类]程序人生 (2)
- [网站分类]SQL Server (2)
- WCF (3)
- 编程技巧 (2)
- 模式架构 (2)
- 分析设计 (4)
- 生活随笔 (0)
- 软件工程 (1)
- Android实例 (2)
最新评论
-
zilong0536:
楼主您好:
请问发表博文支持图片的功能怎么实现啊,一直没有思路 ...
新浪微博开放平台开发-android客户端(3) -
nicegege:
小弟 学习了
帮助中国移动设计10086的排队小模块 -
zl7824516:
用什么技术没说啊
通告(公告),消息(站内短信),提醒的设计:通告 -
virusswb:
源码下载: SinaWeibo2 源码下载之后,将后缀改为ra ...
新浪微博开放平台开发-android客户端(3) -
Jimmyxu0311:
找不到源码下载
新浪微博开放平台开发-android客户端(3)
我不知道NH的ORM具体如何实现的,我的想法就是通过字段名称和属性名称的对应关系来实现赋值。
简单的类型比较好做,直接赋值就可以了。简单类型是说int,string之类的。
有几个需要注意的地方:
1 属性的类型是另外一个类
2 属性是一个集合
3 类有两个属性的类型是同一个类,例如:种子有用量及其单位,和产量及其单位,用量的单位和产量的单位是一个类型
4 属性嵌套,就是属性的这个类型里面的属性还可能是另外一个类
解决办法:
1 用不同的attribute,普通的类型直接赋值,另外一个类的话就交给另外一个类去负责具体的映射
2 分两次映射,然后集合赋值给商品的属性,觉得不是很好,有没有更好的办法呢?
3 添加前缀来区分两个相同类型的不同属性
4 嵌套,一层一层解决
还有就是关于集合,例如:商品的包装规格集合。如何映射呢?是不是需要集合的时候,再次根据商品的ID查询包装规格集合,然后赋值给商品的包装规格属性呢?
那就是两次访问数据库了,我想要一次访问,可以实现吗?
结果集就是下面的格式,第一个table是商品,第二个table是包装规格,循环第一个table映射出来一个商品,但是在映射的时候如果发现属性是List类型,实际上是需要第二个结果集来配合了。如何传第二个的结果集呢?我想不出来。我的解决办法就是一个一个的映射,先映射商品,赋值给一个商品的实例。然后映射包装规格,赋值给一个List,然后把这个List赋值给商品的包装规格属性。
不知道能否在映射商品的同时就映射包装规格集合吗?
数据库的查询结果
先定义两个attribute,一个用在属性上面,用来映射列
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace BeautyCode.SQLite.ConApp.Common
{
[AttributeUsage(AttributeTargets.Property)]
public class ColumnAttribute : Attribute
{
private string _columnType;
/// <summary>
/// 数据库字段类型
/// </summary>
public string ColumnType
{
get { return _columnType; }
set { _columnType = value; }
}
private string _columnName;
/// <summary>
/// 数据库字段名称
/// </summary>
public string ColumnName
{
get { return _columnName; }
set { _columnName = value; }
}
private int _length;
/// <summary>
/// 数据库字段长度
/// </summary>
public int Length
{
get { return _length; }
set { _length = value; }
}
private bool _isIdentity;
/// <summary>
/// 是否标识列
/// </summary>
public bool IsIdentity
{
get { return _isIdentity; }
set { _isIdentity = value; }
}
public ColumnAttribute(string columnName, string columnType, int len, bool isIdentity)
{
this._columnType = columnType;
this._columnName = columnName;
this._length = len;
this._isIdentity = isIdentity;
}
public ColumnAttribute(string columnName)
: this(columnName, string.Empty, 0, false)
{
}
}
}
一个用在属性是复杂类型,也就是说属性的类型是另外一个类
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace BeautyCode.SQLite.ConApp.Common
{
[AttributeUsage(AttributeTargets.Property)]
public class ReferenceAttribute : Attribute
{
private Type _referenceClassType;
public Type ReferenceClassType
{
get { return _referenceClassType; }
set { _referenceClassType = value; }
}
private string _preFix;
public string PreFix
{
get { return _preFix; }
set { _preFix = value; }
}
private ReferenceType _referenceType;
public ReferenceType ReferenceType
{
get { return _referenceType; }
set { _referenceType = value; }
}
public ReferenceAttribute(Type type, string preFix,ReferenceType referenceType)
{
this._referenceClassType = type;
this._preFix = preFix;
this._referenceType = referenceType;
}
}
public enum ReferenceType
{
Ojbect,
Collection
}
}
给这两种attribute类型定义两个映射方法
{
public static void ColToProperty(ref PropertyInfo p,object entity, IDataReader reader,string preFix)
{
string columnName = string.IsNullOrWhiteSpace(preFix) ? p.Name : preFix + p.Name;
if (p.PropertyType.IsEnum)
{
p.SetValue(entity, Enum.Parse(p.PropertyType, reader[columnName].ToString()), null);
}
else
{
p.SetValue(entity, reader[columnName], null);
}
}
}
public class ReferenceMapper
{
public static object ReferenceToEntity( Type type, string preFix, IDataReader reader, Common.ReferenceType referenceType)
{
string columnName = string.Empty;
object obj = Activator.CreateInstance(type);
PropertyInfo[] ps = obj.GetType ().GetProperties();
for (int i = 0; i < ps.Length; i++)
{
columnName = string.IsNullOrWhiteSpace(preFix) ? ps[i].Name : preFix + ps[i].Name;
object[] attributes = ps[i].GetCustomAttributes(false);
if (attributes.Length > 0)
{
if (referenceType == Common.ReferenceType.Ojbect)
{
if (attributes[0] is Common.ColumnAttribute)
{
if (string.IsNullOrWhiteSpace(reader[columnName].ToString()))
continue;
ColumnMapper.ColToProperty(ref ps[i], obj, reader, preFix);
}
if (attributes[0] is Common.ReferenceAttribute)
{
ps[i].SetValue(obj, ReferenceMapper.ReferenceToEntity((attributes[0] as Common.ReferenceAttribute).ReferenceClassType,
(attributes[0] as Common.ReferenceAttribute).PreFix, reader, (attributes[0] as Common.ReferenceAttribute).ReferenceType), null);
}
}
}
}
return obj;
}
}
实例实体类
public enum ProductType
{
Seed = 1,
Fertilizer = 2,
Pesticide = 4
}
public class Seed : Common.BaseEntity
{
[Column("SeedID")]
public Guid SeedID
{ get; set; }
[Column("SeedName")]
public string SeedName
{ get; set; }
[Column ("ProductType")]
public ProductType ProductType
{
get;
set;
}
[Column("PlantAmount")]
public decimal PlantAmount
{ get; set; }
[Reference(typeof(Unit), "PlantAmount", Common.ReferenceType.Ojbect )]
public Unit PlantAmountUnit
{ get; set; }
[Column("OutputAmount")]
public decimal OutputAmount
{ get; set; }
[Reference(typeof(Unit), "OutputAmount", Common.ReferenceType.Ojbect )]
public Unit OutputAmountUnit
{ get; set; }
//[Reference (typeof(SeedPkgSpec),"", Common.ReferenceType.Collection )]
public List<SeedPkgSpec> PkgSpecs
{
get;
set;
}
}
using System.Collections.Generic;
using System.Linq;
using System.Text;
using BeautyCode.SQLite.ConApp.Common;
namespace BeautyCode.SQLite.ConApp.Entity
{
public class SeedPkgSpec : Common.BaseEntity
{
[Column("PkgSpecID")]
public Guid PkgSpecID
{ get; set; }
[Column("SeedID")]
public Guid SeedID
{ get; set; }
[Column("PkgAmount")]
public decimal PkgAmount
{ get; set; }
[Reference(typeof(Unit ),"PkgAmount", Common.ReferenceType.Ojbect ) ]
public Unit PkgUnit
{ get; set; }
[Reference(typeof(PkgSpec), "", Common.ReferenceType.Ojbect )]
public PkgSpec PkgSpec
{
get;
set;
}
}
}
using System.Collections.Generic;
using System.Linq;
using System.Text;
using BeautyCode.SQLite.ConApp.Common;
namespace BeautyCode.SQLite.ConApp.Entity
{
public class PkgSpec:Common.BaseEntity
{
[Column("PkgSpecCode")]
public string PkgSpecCode
{ get; set; }
[Column("PkgSpecName")]
public string PkgSpecName
{ get; set; }
}
}
using System.Collections.Generic;
using System.Linq;
using System.Text;
using BeautyCode.SQLite.ConApp.Common;
namespace BeautyCode.SQLite.ConApp.Entity
{
public class Unit : Common.BaseEntity
{
[Column("UnitCode")]
public string UnitCode
{ get; set; }
[Column("UnitCnName")]
public string UnitCnName
{ get; set; }
[Column( "UnitEnName")]
public string UnitEnName
{ get; set; }
}
}
映射接口,每个实体实现下面的接口
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
namespace BeautyCode.SQLite.ConApp.EntityMapper
{
public interface IEntityMapper<T> where T:Common.BaseEntity
{
T RowToEntity(IDataReader reader);
DataRow EntityToRow(T entity);
}
}
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
using System.Data;
namespace BeautyCode.SQLite.ConApp.EntityMapper
{
public class SeedMapper : IEntityMapper<Entity.Seed>
{
#region IEntityMapper<Seed> Members
public Entity.Seed RowToEntity(IDataReader reader)
{
Entity.Seed entity = new Entity.Seed();
PropertyInfo[] ps = typeof(Entity.Seed).GetProperties();
for (int i = 0; i < ps.Length; i++)
{
object[] attributes = ps[i].GetCustomAttributes(false);
if (attributes.Length > 0)
{
if (attributes[0] is Common.ColumnAttribute)
{
ColumnMapper.ColToProperty(ref ps[i], entity, reader, null);
}
if (attributes[0] is Common.ReferenceAttribute)
{
ps[i].SetValue(entity, ReferenceMapper.ReferenceToEntity((attributes[0] as Common.ReferenceAttribute).ReferenceClassType,
(attributes[0] as Common.ReferenceAttribute).PreFix, reader, (attributes[0] as Common.ReferenceAttribute).ReferenceType), null);
}
}
}
return entity;
}
public System.Data.DataRow EntityToRow(Entity.Seed entity)
{
throw new NotImplementedException();
}
#endregion
}
}
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
using System.Data;
namespace BeautyCode.SQLite.ConApp.EntityMapper
{
public class SeedPkgSpecMapper:IEntityMapper<Entity.SeedPkgSpec >
{
#region IEntityMapper<SeedPkgSpec> Members
public Entity.SeedPkgSpec RowToEntity(IDataReader reader)
{
Entity.SeedPkgSpec entity = new Entity.SeedPkgSpec();
PropertyInfo[] ps = typeof(Entity.SeedPkgSpec).GetProperties();
for (int i = 0; i < ps.Length; i++)
{
object[] attributes = ps[i].GetCustomAttributes(false);
if (attributes.Length > 0)
{
if (attributes[0] is Common.ColumnAttribute)
{
if (string.IsNullOrWhiteSpace(reader[ps[i].Name].ToString()))
continue;
ColumnMapper.ColToProperty(ref ps[i], entity, reader, null);
}
if (attributes[0] is Common.ReferenceAttribute)
{
ps[i].SetValue(entity, ReferenceMapper.ReferenceToEntity((attributes[0] as Common.ReferenceAttribute).ReferenceClassType,
(attributes[0] as Common.ReferenceAttribute).PreFix, reader, (attributes[0] as Common.ReferenceAttribute).ReferenceType), null);
}
}
}
return entity;
}
public System.Data.DataRow EntityToRow(Entity.SeedPkgSpec entity)
{
throw new NotImplementedException();
}
#endregion
}
}
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
namespace BeautyCode.SQLite.ConApp.EntityMapper
{
public class UnitMapper:IEntityMapper<Entity.Unit>
{
#region IEntityMapper<Unit> Members
public Entity.Unit RowToEntity(System.Data.IDataReader reader)
{
Entity.Unit entity = new Entity.Unit();
PropertyInfo[] ps = typeof(Entity.Unit).GetProperties();
for (int i = 0; i < ps.Length; i++)
{
object[] attributes = ps[i].GetCustomAttributes(false);
if (attributes.Length > 0)
{
if (attributes[0] is Common.ColumnAttribute)
{
if (string.IsNullOrWhiteSpace(reader[ps[i].Name].ToString()))
continue;
ColumnMapper.ColToProperty(ref ps[i], entity, reader, null);
}
if (attributes[0] is Common.ReferenceAttribute)
{
ps[i].SetValue(entity, ReferenceMapper.ReferenceToEntity((attributes[0] as Common.ReferenceAttribute).ReferenceClassType,
(attributes[0] as Common.ReferenceAttribute).PreFix, reader, (attributes[0] as Common.ReferenceAttribute).ReferenceType), null);
}
}
}
return entity;
}
public System.Data.DataRow EntityToRow(Entity.Unit entity)
{
throw new NotImplementedException();
}
#endregion
}
}
上面的代码结构其实还是可以优化的,因为每个实体类的映射方法,里面的代码大量的重复,只是初始化的类型不一样,还有重构的余地。
目前还差的就是映射集合,在映射商品的时候一起映射集合。
项目可以从http://beautycode.codeplex.com/下载,或者是/Files/virusswb/BeautyCode.SQLite.ConApp.rar
发表评论
-
NET 应用架构指导 V2 学习笔记(十六) 服务层设计指导
2010-06-04 00:13 525如果你的应用是通 ... -
NET 应用架构指导 V2 学习笔记(十七) 组件设计指导
2010-06-05 00:48 626组件提供了一种将 ... -
NET 应用架构指导 V2 学习笔记(十八) 表现层组件设计指导
2010-06-05 21:09 493本章讲述的是你在设计用户界面组件和表现层逻辑组件的时候应该 ... -
NET 应用架构指导 V2 学习笔记(十九) 表现层组件设计指导
2010-06-06 06:15 5585 决定数据绑定的 ... -
NET 应用架构指导 V2 学习笔记(二十) 业务组件设计指导
2010-06-07 06:58 578前言 业务组件 ... -
微软企业库5.0学习笔记(四十二)异常处理模块
2010-06-14 00:04 804企业库的异常处理 ... -
关于程序员在30岁、35岁之后怎么办的新思考
2010-06-14 10:40 594首先给大家问个好 ... -
NET 应用架构指导 V2 学习笔记(二十四) 跨层关注问题
2010-06-17 20:00 549概况 大部分的 ... -
微软企业库5.0学习笔记(四十三)数据验证模块
2010-06-19 08:07 962概况 任何接受用户或者是其他系统输入的应用,一定要确保 ... -
关于项目进度慢的思考----如何提高整体开发效率
2010-06-21 23:42 771我们都是软件行业 ... -
微软企业库5.0学习笔记(四十四)实战数据验证模块
2010-06-23 19:22 7951 在业务对象上添加验证 添加对程序集【Microso ... -
微软企业库5.0学习笔记(四十五)实战数据验证模块----高级篇
2010-06-24 19:41 9471、添加自定义的提示信息 验证失败的提示信息可以自定义 ... -
面向对象类设计的五大原则(一)单一职责原则Single Responsibility Principle
2010-06-29 15:45 735引言 面向对象类设计,或者说是面向对象设计,有五大原则 ... -
《深入浅出设计模式-中文版》读书笔记 开篇乱弹(一)
2010-07-01 06:42 621oreilly的《Head.First ... -
《深入浅出设计模式-中文版》读书笔记-继承与组合(三)
2010-07-03 16:53 578经过上一次的改造 ... -
《深入浅出设计模式-中文版》读书笔记-观察者模式(四)
2010-07-06 06:34 602今天要接触的是观 ... -
系统内部模块(子系统)之间的耦合以及模块(子系统)划分
2010-07-14 13:02 789题外话 最近已经在努力学习了,学习基本功,学习设计模式 ... -
《深入浅出设计模式-中文版》读书笔记-工厂模式(五)
2010-07-16 12:46 669今天给大家带来的是:工厂模式。 我们在代码中创建一个对 ... -
Head.First.Object-Oriented.Design.and.Analysis《深入浅出面向对象的分析与设计》读书笔记(一)
2010-07-18 21:47 638题外话 又是一本Head.First系列的书,这个系列 ... -
Head.First.Object-Oriented.Design.and.Analysis《深入浅出面向对象的分析与设计》读书笔记(二)
2010-07-20 07:18 657今天的话题是收集需求。 Gathering Requi ...
相关推荐
【内容概要】:在C#中通过学习使用Attribute,实现一个简单的ORM框架。里面主要有两部分的内容,学习使用Attribute获得设定值;学习通过反射获取属性的值 【适应人群】:初级工程师。但需要对反射、Attribute有一定...
利用Attribute简化Unity框架IOC注入 例子还不错 想学习的人可以看看
包含2篇attribute高级应用文章,以及相应的代码。 代码关键处,都有详细注释。 看过后,你会对attribute,context有更深刻的认识
c# 利用Attribute 添加函数执行条件 解除工厂if else 或 switch case的 判断 可以先看看博客 内容一样的这里只是方便下载 https://blog.csdn.net/sinat_30224769/article/details/82144688
这是我Blog(http://blog.csdn.net/RonoTian)中的系列文章《实现自己的ORM》系列的配套资源,如果你需要详细的了解MiniORM的相关实现,那请自己查看我Blog中相关文章。
python3 server.py 127.0.0.1 8888 ...AttributeError: module ‘os’ has no attribute ‘exit’ 部分代码入下: from socket import * import sys,os #实现登录 def do_login(s,user,name,addr): for i in user: i
AttributeError: module 'tensorflow.compat.v1' has no attribute 'contrib'的问题您具体怎么解决问题具体解决的seq_loss.py文件
该示例代码是针对asp.net core mvc权限管理的一种实现方式,不一定是最好的,但是能满足权限的有效控制
利用AE+C#实现 框选要素 弹出要素属性值的地图查询功能
Attribute在NET中的应用 讲解在NET中如何自定义自己的特性(Attribute)如何使用
Attribute Aware Pooling for Pedestrian Attribute Recognition
File Attribute
你是否对 c# attribute 感到不解,如在有一个类定义前加了一个[]是代表什么,这就是c# 的attribute ,这里有两个简单直观的实例,让你直观的、容易的理解attribute的用法,
C#的Attribute
c#特性(Attribute)简单示例,适合初学者
c语言中不常用的知识,__attribute__的使用方法
Property和Attribute的区别
gcc 函数属性 attribute ((constructor))使用demo demo演示了gpio_init(void) 和 key_init(void)如何设置__attribute__ ((constructor)) 属性,同时演示了添加key.c文件的不需要修改main.c的方法,此方法能减少对...
MyOrm,简单的Attribute和反射 可以定义两种特性,一个数据数据库表绑定特性,名为BindTableAttribute,用于将一个对象类型绑定到一个指定表名称的数据表上;还有一个数据库字段绑定特性,名为BindFieldAttribute,...
此文档详细的介绍了.NET下 自定义Attribute的应用,对于理解.NET AOP下的技术实现非常有帮助