分享高效的实体类操作类,分析其优势,可自己写替代EF的ORM框架

下面是代码分析:

C# code
publicclass Dog
{
   
publicint? Age { get; set; }
   
public Guid Id { get; set; }
   
publicstring Name { get; set; }
   
publicfloat? Weight { get; set; }

   
publicint IgnoredProperty { get { return1; } }
}           
           
var guid = Guid.NewGuid();
var dog = connection.Query<Dog>("select Age = @Age, Id = @Id", new { Age = (int?)null, Id = guid });


这个查询,返回的是Dog类的集合,参数是一个匿名类,2个属性(Age和Id),其实除了匿名属性作为参数,实体类本身也可以作为参数,这意味着你可以很方便得从一个实体作为条件,获取其相关联的其它实体,写代码会很方便,无需自己写参数构造过程了。

在看这段代码:
C# code
connection.Execute(@"insert MyTable(colA, colB) values (@a, @b)",
   
new[] { new { a=1, b=1 }, new { a=2, b=2 }, new { a=3, b=3 } }
  ).IsEqualTo(
3); // 3 rows inserted: "1,1", "2,2" and "3,3"



这是非常有意义的写法,当我们批量更新一个List<T>内的实体的修改是,直接把这个List作为参数传递给它即可,Sql语句自己定义。而以前的写法都是循环集合中的每个实体,然后创建参数,对数据库提交修改。

最后看这段代码:

C# code
   class User
        {
           
publicint Id { get; set; }
           
publicstring Name { get; set; }
        }
       
class Post
        {
           
publicint Id { get; set; }
           
public User Owner { get; set; }
           
publicstring Content { get; set; }
           
public Comment Comment { get; set; }
        }
       
publicvoid TestMultiMap()
        {
           
var createSql =@"
                create table #Users (Id int, Name varchar(20))
                create table #Posts (Id int, OwnerId int, Content varchar(20))

                insert #Users values(99, 'Sam')
                insert #Users values(2, 'I am')

                insert #Posts values(1, 99, 'Sams Post1')
                insert #Posts values(2, 99, 'Sams Post2')
                insert #Posts values(3, null, 'no ones post')
";
            connection.Execute(createSql);

           
var sql =
@"select * from #Posts p
left join #Users u on u.Id = p.OwnerId
Order by p.Id
";

           
var data = connection.Query<Post, User, Post>(sql, (post, user) => { post.Owner = user; return post; }).ToList();
           
var p = data.First();

            p.Content.IsEqualTo(
"Sams Post1");
            p.Id.IsEqualTo(
1);
            p.Owner.Name.IsEqualTo(
"Sam");
            p.Owner.Id.IsEqualTo(
99);

            data[
2].Owner.IsNull();

            connection.Execute(
"drop table #Users drop table #Posts");
        }



这是多实体联合查询的示例,通过传递一个关系函数,得到一个根实体,访问根实体Post的属性User,可以得到相关联的User,这在多表联合查询中修改中非常有意义,而这个根实体其实可以用动态实体来替代,这样就非常完美了。

有了上面这些强大的基础功能,我们只要封装下从数据库中映射的实体类的基本SELECT、INSERT、UPDATE、DELETE语句,那么连SQL语句部分都可以不用写了,一个非常强大的ORM框架就此诞生,还支持动态类型查询。

这个强大的实体类只能在直接访问数据库的情况下使用,如果要在远程方法中调用(如WCF),则必须做大的改动,而Silverlight对匿名实体类的处理又有所不同,因为不支持TypeDescriptor类,将无法动态构造属性说明,因此必须动态创建一个新的类型来处理,这个处理难度非常大,目前正在设计阶段,主要技术问题都已解决,正在ORM框架的构建中。

本人业余编程,自认为水平已经很专业了(仅限C#),如果有C++高手可以指点下C++下面的实体类处理,我好让设计的动态实体类可以更多的跨语言,跨平台。

posted @ 2012-04-14 14:41  晴天有时下鱼  阅读(394)  评论(0编辑  收藏  举报