[求助]业务实体类初始化时如何初始化其它的业务实体(多个)

时间:2021-03-12 09:53:46

public class StudentInfo: StudentBase
    {
        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="studID"></param>
        public StudentInfo(string studID):base(studID)
        {
            using(var db = new CetDataBase())
            {
                IQueryable<RegTab> cetInfoQuery = from s in db.RegTab
                              where s.Xh == studID
                              select s;
                foreach (var cetInfo in cetInfoQuery)
                {
  
                }
            }
        }
 
        public string sfzh { get; set; }
 
        public virtual ICollection<CetInfo> CetInfo { get; set; }
    }


测试代码如上,目前还在学习中,也许不一定对,请大家指点,
说明,其中CetInfo 是一个业务实体类,因为一个StudentInfo 可以有多个CetInfo ,请问初始化时,如何给这个ICollection<CetInfo>  CetInfo 初始化 

我本来想通过数据库查询出来的结果给CetInfo 初始化,但查出来的结果是IQueryable<RegTab>类型的,如何转换成ICollection<CetInfo>呢?

或者其它的办法有没有,比如延迟查询,当需要的时候再初始化CetInfo属性,但是到这一步的时候,仍然面临同样的问题,IQueryable<RegTab>如何转换为ICollection<CetInfo>? 

[求助]业务实体类初始化时如何初始化其它的业务实体(多个)

18 个解决方案

#1


public virtual  ICollection<CetInfo> CetInfo { get; set; }

这里换成IEnumerable 同时建议使用lazy

所以最终就是public virtualI  Lazy<IEnumerable<CetInfo>> CetInfo { get; set; }

你想对他定义就是

CetInfo =()={  //这块对 其进行数据查询工作并返回数据集合} //当然这里是lazy查询所以你甚至可以先把所有外键值完全暂存在一个list里,然后后面一次性查询如内存在根据外键过滤,这个过程类似EF地include


当然所有以上讨论基于你自己去实现他,如果你本身是使用EF地话,这些工作根本不需要你做,EF全会自动帮你完成

#2


CetInfo为什么要设计成virtual,还有类需要继承StudentInfo吗?

/// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="studID"></param>
        public StudentInfo(string studID):base(studID)
        {
            using(var db = new CetDataBase())
            {
                IQueryable<RegTab> cetInfoQuery = from s in db.RegTab
                              where s.Xh == studID
                              select s;
                CetInfo = new List<CetInfo>();
                CetInfo cet = null;
                foreach (var _regTab in cetInfoQuery)
                {
                          cet = new CetInfo();
                          cet.xxxx = _regTab.xxxx;
                          CetInfo.Add(cet);
                }
            }
        }

#3


另外顺带说一句,看你的做法本地就是EF

那么什么都不需要做。 把 定义改为
public virtual IQueryable<CetInfo> CetInfo { get; set; }

前面直接 CetInfo= from s in db.RegTab
                              where s.Xh == studID
                              select s;
即可

#4


在另外建议,lz自己研究一下EF地join和include地使用方式(呵呵,其实你要做地东西EF已经完全实现了,不需要你在重复去造了)

#5


我知道这是EF的做法,但是当一个系统比较庞大之后,我发现EF仅仅是解决了实体与表的映射,实体与实体之间的逻辑关系,还是需要自己写,这是UML需要解决的问题,和EF无关。
实体也分大实体,小实体,有些小实体可能和数据库中的表对应,但大的实体是一些小实体组成的,EF能解决这样的问题吗?

#6


引用 3 楼 wanghui0380 的回复:
另外顺带说一句,看你的做法本地就是EF

那么什么都不需要做。 把 定义改为
public virtual IQueryable<CetInfo> CetInfo { get; set; }

前面直接 CetInfo= from s in db.RegTab
                              where s.Xh == studID
                              select s;
即可


定义不一样,CetInfo是一个实体类,RegTab是一个表实体类,咦,我怎么有点乱,我再想想。

#7


引用 2 楼 xdashewan 的回复:
CetInfo为什么要设计成virtual,还有类需要继承StudentInfo吗?

/// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="studID"></param>
        public StudentInfo(string studID):base(studID)
        {
            using(var db = new CetDataBase())
            {
                IQueryable<RegTab> cetInfoQuery = from s in db.RegTab
                              where s.Xh == studID
                              select s;
                CetInfo = new List<CetInfo>();
                CetInfo cet = null;
                foreach (var _regTab in cetInfoQuery)
                {
                          cet = new CetInfo();
                          cet.xxxx = _regTab.xxxx;
                          CetInfo.Add(cet);
                }
            }
        }


我也是这个思路,我先试试。

#8


其实你这个问题提的很好,看来你已经注意到实体和模型不是固定的这个事实了
至于有关转换方面,你可以参考我1楼回复地Lazy<IEnumerable<CetInfo>>

或者直接采用 IEnumerable<CetInfo> 采用这种方式地时候,则可以考虑使用 yield 关键字去延迟查询

ps:你这个过程实际上已经快接近正式项目架构师的方向了,当然我可以提出另外一个问题看看你能否自己推论一下如何解决
你的架构描述很不错,但是他能解决单个StudentInfo实例的表达,但是如果是 List<StudentInfo>呢,每个StudentInfo都单独去查一次表??1000个元素地StudentInfo列表就要查1000次表?? 很明显这个方案在实际使用上是符合业务逻辑,但是却缺乏性能上地考虑

#9


该回复于2014-05-16 13:27:46被管理员删除

#10


引用 8 楼 wanghui0380 的回复:
其实你这个问题提的很好,看来你已经注意到实体和模型不是固定的这个事实了
至于有关转换方面,你可以参考我1楼回复地Lazy<IEnumerable<CetInfo>>

或者直接采用 IEnumerable<CetInfo> 采用这种方式地时候,则可以考虑使用 yield 关键字去延迟查询

ps:你这个过程实际上已经快接近正式项目架构师的方向了,当然我可以提出另外一个问题看看你能否自己推论一下如何解决
你的架构描述很不错,但是他能解决单个StudentInfo实例的表达,但是如果是 List<StudentInfo>呢,每个StudentInfo都单独去查一次表??1000个元素地StudentInfo列表就要查1000次表?? 很明显这个方案在实际使用上是符合业务逻辑,但是却缺乏性能上地考虑


这个也是我最近在苦恼的,虽然单个实体的问题解决了,但对于统计类的问题,就不好解决,而对于IList类型的,难道每个都要去实例化?

有没有相关的书籍介绍看下。没人指导,确实很苦恼啊。

还有,不知道老兄的实体和模型是什么意思,因为本人不是专业的人员,有时候一些用语的定义不是很一样,我还怕造成误解呢。

其实最近,正在看一本书叫《大象:thinking in uml》,才知道统一过程这个东西,然后才突然醒悟,妈呀,喊了这么多年的面向对象,其实还不是真正的面向对象,正好,以前看的ORM框架,一直也没怎么用,就试着将统一过程和ORM的模式应用到里面吧,ORM还好说,EF基本将工作已经完成,用了时候,搜索搜索,还能解决问题,但是应用统一过程的时候,却发现各种不适应。就如本例,真正的业务实例是CetInfo,但数据库中存放的是RegTab表,虽然EF生成了RegTab的表实体,已经不用和数据库直接打交道了,但CetInfo和RegTab表实体,却又难以建立关联,如果仅是实例化一个的话还好说,将CetInfo这个业务用例的所有属性一一赋值就好了,但是对于IList就又不知道如何是好了。

还请高手指点一下。

#11


Lazy类,确实是一个不错的选择,这样对资源的占用将小很多,但还不是很明白,什么时候会初始化,慢慢学习吧。

#12



public class StudentInfo: StudentBase
    {
        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="studID"></param>
        public StudentInfo(string studID):base(studID)
        {
            using(var db = new CetDataBase())
            {
                IEnumerable<RegTab> regQuery = from s in db.RegTab
                                where s.Xh == studID
                                select s;
                List<CetInfo> _CetInfos = new List<CetInfo>();
                foreach (var reg in regQuery)
                {
                    CetInfo cetInfo = new CetInfo();
                    cetInfo.RegID = reg.RegID;
                    cetInfo.LastDate = reg.LastDate;
                    _CetInfos.Add(cetInfo);
                }
                this.CetInfos = _CetInfos;
            }
        }

        public string sfzh { get; set; }

        public List<CetInfo> CetInfos { get; set; }
    }


最后写成这样了,但总感觉不对,请高手指点一下啊。

#13


你可以使用AutoMapper
http://www.cnblogs.com/xishuai/p/3691787.html

#14


引用 楼主 yixian2007 的回复:
说明,其中CetInfo 是一个业务实体类,因为一个StudentInfo 可以有多个CetInfo ,请问初始化时,如何给这个ICollection<CetInfo>  CetInfo 初始化 

我本来想通过数据库查询出来的结果给CetInfo 初始化,但查出来的结果是IQueryable<RegTab>类型的,如何转换成ICollection<CetInfo>呢?


两个问题。最重要地,“实体”根本跟数据库没有直接关系。实体是用来在各个层次之间进行通讯的,它只作基本的“内存中的”数据处理。逻辑层会对数据库“增删改查”,那能跑到实体类里边去读取数据库的?

作为一个低级的“技术”问题,如果你想得到ICollection<T>,可以使用Linq的ToList()方法,得到的集合就具有那个接口。

#15


如果你对

         CetInfo= from s in db.RegTab
                               where s.Xh == studID
                               select s;

不满意,你应该使用一个BLL功能方法来封装更有意义的查询操作,而不是乱改什么实体定义。

我确实遇到过自称为研究了“三层”6、7年的人在实体类里乱写数据库查询,这样的人基本上都改行做销售了,而没有做出什么产品。因为一旦做灵活一点的东西,过度单一的模型让他就根本纠结不清了。

#16


引用 15 楼 sp1234 的回复:
如果你对

         CetInfo= from s in db.RegTab
                               where s.Xh == studID
                               select s;

不满意,你应该使用一个BLL功能方法来封装更有意义的查询操作,而不是乱改什么实体定义。

我确实遇到过自称为研究了“三层”6、7年的人在实体类里乱写数据库查询,这样的人基本上都改行做销售了,而没有做出什么产品。因为一旦做灵活一点的东西,过度单一的模型让他就根本纠结不清了。


封装操作我明白了,确实不应该放在这个地方,因为我这个是测试代码,还在实验中,所以暂时放这里了,你的建议很好,但我仍然很纠结,这个功能或者方法应该放哪里呢?

不过我现在纠结的不是这个方法放哪里,而是查询出来的类型和实体的类型不匹配。或者说我还是没有真正理解实体与数据库的关系?
又或者这个查询应该在底层查询的时候就将类型转换过来?

#17


大哥,有没有一个例子给我看下,学习一下。

我实在是想不清楚啊。

#18


另外,我这个不是三层结构啊。

底层是EF,再上一层是对EF进行操作的层,中间是业务实体,这一层才是真正的现实世界的对象,再往上业务层,再往上是表现层。

现在我卡在中间这个业务实体层了,根源在于操作EF出来的结果,并不是真正的业务对象,但是这业务实体层比EF操作层要高一层,又不能在里面用业务实体层。郁闷的很。

也请高手们看下,我这样分层对不对。

#1


public virtual  ICollection<CetInfo> CetInfo { get; set; }

这里换成IEnumerable 同时建议使用lazy

所以最终就是public virtualI  Lazy<IEnumerable<CetInfo>> CetInfo { get; set; }

你想对他定义就是

CetInfo =()={  //这块对 其进行数据查询工作并返回数据集合} //当然这里是lazy查询所以你甚至可以先把所有外键值完全暂存在一个list里,然后后面一次性查询如内存在根据外键过滤,这个过程类似EF地include


当然所有以上讨论基于你自己去实现他,如果你本身是使用EF地话,这些工作根本不需要你做,EF全会自动帮你完成

#2


CetInfo为什么要设计成virtual,还有类需要继承StudentInfo吗?

/// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="studID"></param>
        public StudentInfo(string studID):base(studID)
        {
            using(var db = new CetDataBase())
            {
                IQueryable<RegTab> cetInfoQuery = from s in db.RegTab
                              where s.Xh == studID
                              select s;
                CetInfo = new List<CetInfo>();
                CetInfo cet = null;
                foreach (var _regTab in cetInfoQuery)
                {
                          cet = new CetInfo();
                          cet.xxxx = _regTab.xxxx;
                          CetInfo.Add(cet);
                }
            }
        }

#3


另外顺带说一句,看你的做法本地就是EF

那么什么都不需要做。 把 定义改为
public virtual IQueryable<CetInfo> CetInfo { get; set; }

前面直接 CetInfo= from s in db.RegTab
                              where s.Xh == studID
                              select s;
即可

#4


在另外建议,lz自己研究一下EF地join和include地使用方式(呵呵,其实你要做地东西EF已经完全实现了,不需要你在重复去造了)

#5


我知道这是EF的做法,但是当一个系统比较庞大之后,我发现EF仅仅是解决了实体与表的映射,实体与实体之间的逻辑关系,还是需要自己写,这是UML需要解决的问题,和EF无关。
实体也分大实体,小实体,有些小实体可能和数据库中的表对应,但大的实体是一些小实体组成的,EF能解决这样的问题吗?

#6


引用 3 楼 wanghui0380 的回复:
另外顺带说一句,看你的做法本地就是EF

那么什么都不需要做。 把 定义改为
public virtual IQueryable<CetInfo> CetInfo { get; set; }

前面直接 CetInfo= from s in db.RegTab
                              where s.Xh == studID
                              select s;
即可


定义不一样,CetInfo是一个实体类,RegTab是一个表实体类,咦,我怎么有点乱,我再想想。

#7


引用 2 楼 xdashewan 的回复:
CetInfo为什么要设计成virtual,还有类需要继承StudentInfo吗?

/// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="studID"></param>
        public StudentInfo(string studID):base(studID)
        {
            using(var db = new CetDataBase())
            {
                IQueryable<RegTab> cetInfoQuery = from s in db.RegTab
                              where s.Xh == studID
                              select s;
                CetInfo = new List<CetInfo>();
                CetInfo cet = null;
                foreach (var _regTab in cetInfoQuery)
                {
                          cet = new CetInfo();
                          cet.xxxx = _regTab.xxxx;
                          CetInfo.Add(cet);
                }
            }
        }


我也是这个思路,我先试试。

#8


其实你这个问题提的很好,看来你已经注意到实体和模型不是固定的这个事实了
至于有关转换方面,你可以参考我1楼回复地Lazy<IEnumerable<CetInfo>>

或者直接采用 IEnumerable<CetInfo> 采用这种方式地时候,则可以考虑使用 yield 关键字去延迟查询

ps:你这个过程实际上已经快接近正式项目架构师的方向了,当然我可以提出另外一个问题看看你能否自己推论一下如何解决
你的架构描述很不错,但是他能解决单个StudentInfo实例的表达,但是如果是 List<StudentInfo>呢,每个StudentInfo都单独去查一次表??1000个元素地StudentInfo列表就要查1000次表?? 很明显这个方案在实际使用上是符合业务逻辑,但是却缺乏性能上地考虑

#9


该回复于2014-05-16 13:27:46被管理员删除

#10


引用 8 楼 wanghui0380 的回复:
其实你这个问题提的很好,看来你已经注意到实体和模型不是固定的这个事实了
至于有关转换方面,你可以参考我1楼回复地Lazy<IEnumerable<CetInfo>>

或者直接采用 IEnumerable<CetInfo> 采用这种方式地时候,则可以考虑使用 yield 关键字去延迟查询

ps:你这个过程实际上已经快接近正式项目架构师的方向了,当然我可以提出另外一个问题看看你能否自己推论一下如何解决
你的架构描述很不错,但是他能解决单个StudentInfo实例的表达,但是如果是 List<StudentInfo>呢,每个StudentInfo都单独去查一次表??1000个元素地StudentInfo列表就要查1000次表?? 很明显这个方案在实际使用上是符合业务逻辑,但是却缺乏性能上地考虑


这个也是我最近在苦恼的,虽然单个实体的问题解决了,但对于统计类的问题,就不好解决,而对于IList类型的,难道每个都要去实例化?

有没有相关的书籍介绍看下。没人指导,确实很苦恼啊。

还有,不知道老兄的实体和模型是什么意思,因为本人不是专业的人员,有时候一些用语的定义不是很一样,我还怕造成误解呢。

其实最近,正在看一本书叫《大象:thinking in uml》,才知道统一过程这个东西,然后才突然醒悟,妈呀,喊了这么多年的面向对象,其实还不是真正的面向对象,正好,以前看的ORM框架,一直也没怎么用,就试着将统一过程和ORM的模式应用到里面吧,ORM还好说,EF基本将工作已经完成,用了时候,搜索搜索,还能解决问题,但是应用统一过程的时候,却发现各种不适应。就如本例,真正的业务实例是CetInfo,但数据库中存放的是RegTab表,虽然EF生成了RegTab的表实体,已经不用和数据库直接打交道了,但CetInfo和RegTab表实体,却又难以建立关联,如果仅是实例化一个的话还好说,将CetInfo这个业务用例的所有属性一一赋值就好了,但是对于IList就又不知道如何是好了。

还请高手指点一下。

#11


Lazy类,确实是一个不错的选择,这样对资源的占用将小很多,但还不是很明白,什么时候会初始化,慢慢学习吧。

#12



public class StudentInfo: StudentBase
    {
        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="studID"></param>
        public StudentInfo(string studID):base(studID)
        {
            using(var db = new CetDataBase())
            {
                IEnumerable<RegTab> regQuery = from s in db.RegTab
                                where s.Xh == studID
                                select s;
                List<CetInfo> _CetInfos = new List<CetInfo>();
                foreach (var reg in regQuery)
                {
                    CetInfo cetInfo = new CetInfo();
                    cetInfo.RegID = reg.RegID;
                    cetInfo.LastDate = reg.LastDate;
                    _CetInfos.Add(cetInfo);
                }
                this.CetInfos = _CetInfos;
            }
        }

        public string sfzh { get; set; }

        public List<CetInfo> CetInfos { get; set; }
    }


最后写成这样了,但总感觉不对,请高手指点一下啊。

#13


你可以使用AutoMapper
http://www.cnblogs.com/xishuai/p/3691787.html

#14


引用 楼主 yixian2007 的回复:
说明,其中CetInfo 是一个业务实体类,因为一个StudentInfo 可以有多个CetInfo ,请问初始化时,如何给这个ICollection<CetInfo>  CetInfo 初始化 

我本来想通过数据库查询出来的结果给CetInfo 初始化,但查出来的结果是IQueryable<RegTab>类型的,如何转换成ICollection<CetInfo>呢?


两个问题。最重要地,“实体”根本跟数据库没有直接关系。实体是用来在各个层次之间进行通讯的,它只作基本的“内存中的”数据处理。逻辑层会对数据库“增删改查”,那能跑到实体类里边去读取数据库的?

作为一个低级的“技术”问题,如果你想得到ICollection<T>,可以使用Linq的ToList()方法,得到的集合就具有那个接口。

#15


如果你对

         CetInfo= from s in db.RegTab
                               where s.Xh == studID
                               select s;

不满意,你应该使用一个BLL功能方法来封装更有意义的查询操作,而不是乱改什么实体定义。

我确实遇到过自称为研究了“三层”6、7年的人在实体类里乱写数据库查询,这样的人基本上都改行做销售了,而没有做出什么产品。因为一旦做灵活一点的东西,过度单一的模型让他就根本纠结不清了。

#16


引用 15 楼 sp1234 的回复:
如果你对

         CetInfo= from s in db.RegTab
                               where s.Xh == studID
                               select s;

不满意,你应该使用一个BLL功能方法来封装更有意义的查询操作,而不是乱改什么实体定义。

我确实遇到过自称为研究了“三层”6、7年的人在实体类里乱写数据库查询,这样的人基本上都改行做销售了,而没有做出什么产品。因为一旦做灵活一点的东西,过度单一的模型让他就根本纠结不清了。


封装操作我明白了,确实不应该放在这个地方,因为我这个是测试代码,还在实验中,所以暂时放这里了,你的建议很好,但我仍然很纠结,这个功能或者方法应该放哪里呢?

不过我现在纠结的不是这个方法放哪里,而是查询出来的类型和实体的类型不匹配。或者说我还是没有真正理解实体与数据库的关系?
又或者这个查询应该在底层查询的时候就将类型转换过来?

#17


大哥,有没有一个例子给我看下,学习一下。

我实在是想不清楚啊。

#18


另外,我这个不是三层结构啊。

底层是EF,再上一层是对EF进行操作的层,中间是业务实体,这一层才是真正的现实世界的对象,再往上业务层,再往上是表现层。

现在我卡在中间这个业务实体层了,根源在于操作EF出来的结果,并不是真正的业务对象,但是这业务实体层比EF操作层要高一层,又不能在里面用业务实体层。郁闷的很。

也请高手们看下,我这样分层对不对。