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全会自动帮你完成
这里换成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;
即可
那么什么都不需要做。 把 定义改为
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能解决这样的问题吗?
实体也分大实体,小实体,有些小实体可能和数据库中的表对应,但大的实体是一些小实体组成的,EF能解决这样的问题吗?
#6
定义不一样,CetInfo是一个实体类,RegTab是一个表实体类,咦,我怎么有点乱,我再想想。
#7
我也是这个思路,我先试试。
#8
其实你这个问题提的很好,看来你已经注意到实体和模型不是固定的这个事实了
至于有关转换方面,你可以参考我1楼回复地Lazy<IEnumerable<CetInfo>>
或者直接采用 IEnumerable<CetInfo> 采用这种方式地时候,则可以考虑使用 yield 关键字去延迟查询
ps:你这个过程实际上已经快接近正式项目架构师的方向了,当然我可以提出另外一个问题看看你能否自己推论一下如何解决
你的架构描述很不错,但是他能解决单个StudentInfo实例的表达,但是如果是 List<StudentInfo>呢,每个StudentInfo都单独去查一次表??1000个元素地StudentInfo列表就要查1000次表?? 很明显这个方案在实际使用上是符合业务逻辑,但是却缺乏性能上地考虑
至于有关转换方面,你可以参考我1楼回复地Lazy<IEnumerable<CetInfo>>
或者直接采用 IEnumerable<CetInfo> 采用这种方式地时候,则可以考虑使用 yield 关键字去延迟查询
ps:你这个过程实际上已经快接近正式项目架构师的方向了,当然我可以提出另外一个问题看看你能否自己推论一下如何解决
你的架构描述很不错,但是他能解决单个StudentInfo实例的表达,但是如果是 List<StudentInfo>呢,每个StudentInfo都单独去查一次表??1000个元素地StudentInfo列表就要查1000次表?? 很明显这个方案在实际使用上是符合业务逻辑,但是却缺乏性能上地考虑
#9
#10
这个也是我最近在苦恼的,虽然单个实体的问题解决了,但对于统计类的问题,就不好解决,而对于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
http://www.cnblogs.com/xishuai/p/3691787.html
#14
两个问题。最重要地,“实体”根本跟数据库没有直接关系。实体是用来在各个层次之间进行通讯的,它只作基本的“内存中的”数据处理。逻辑层会对数据库“增删改查”,那能跑到实体类里边去读取数据库的?
作为一个低级的“技术”问题,如果你想得到ICollection<T>,可以使用Linq的ToList()方法,得到的集合就具有那个接口。
#15
如果你对
CetInfo= from s in db.RegTab
where s.Xh == studID
select s;
不满意,你应该使用一个BLL功能方法来封装更有意义的查询操作,而不是乱改什么实体定义。
我确实遇到过自称为研究了“三层”6、7年的人在实体类里乱写数据库查询,这样的人基本上都改行做销售了,而没有做出什么产品。因为一旦做灵活一点的东西,过度单一的模型让他就根本纠结不清了。
CetInfo= from s in db.RegTab
where s.Xh == studID
select s;
不满意,你应该使用一个BLL功能方法来封装更有意义的查询操作,而不是乱改什么实体定义。
我确实遇到过自称为研究了“三层”6、7年的人在实体类里乱写数据库查询,这样的人基本上都改行做销售了,而没有做出什么产品。因为一旦做灵活一点的东西,过度单一的模型让他就根本纠结不清了。
#16
封装操作我明白了,确实不应该放在这个地方,因为我这个是测试代码,还在实验中,所以暂时放这里了,你的建议很好,但我仍然很纠结,这个功能或者方法应该放哪里呢?
不过我现在纠结的不是这个方法放哪里,而是查询出来的类型和实体的类型不匹配。或者说我还是没有真正理解实体与数据库的关系?
又或者这个查询应该在底层查询的时候就将类型转换过来?
#17
大哥,有没有一个例子给我看下,学习一下。
我实在是想不清楚啊。
我实在是想不清楚啊。
#18
另外,我这个不是三层结构啊。
底层是EF,再上一层是对EF进行操作的层,中间是业务实体,这一层才是真正的现实世界的对象,再往上业务层,再往上是表现层。
现在我卡在中间这个业务实体层了,根源在于操作EF出来的结果,并不是真正的业务对象,但是这业务实体层比EF操作层要高一层,又不能在里面用业务实体层。郁闷的很。
也请高手们看下,我这样分层对不对。
底层是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全会自动帮你完成
这里换成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;
即可
那么什么都不需要做。 把 定义改为
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能解决这样的问题吗?
实体也分大实体,小实体,有些小实体可能和数据库中的表对应,但大的实体是一些小实体组成的,EF能解决这样的问题吗?
#6
定义不一样,CetInfo是一个实体类,RegTab是一个表实体类,咦,我怎么有点乱,我再想想。
#7
我也是这个思路,我先试试。
#8
其实你这个问题提的很好,看来你已经注意到实体和模型不是固定的这个事实了
至于有关转换方面,你可以参考我1楼回复地Lazy<IEnumerable<CetInfo>>
或者直接采用 IEnumerable<CetInfo> 采用这种方式地时候,则可以考虑使用 yield 关键字去延迟查询
ps:你这个过程实际上已经快接近正式项目架构师的方向了,当然我可以提出另外一个问题看看你能否自己推论一下如何解决
你的架构描述很不错,但是他能解决单个StudentInfo实例的表达,但是如果是 List<StudentInfo>呢,每个StudentInfo都单独去查一次表??1000个元素地StudentInfo列表就要查1000次表?? 很明显这个方案在实际使用上是符合业务逻辑,但是却缺乏性能上地考虑
至于有关转换方面,你可以参考我1楼回复地Lazy<IEnumerable<CetInfo>>
或者直接采用 IEnumerable<CetInfo> 采用这种方式地时候,则可以考虑使用 yield 关键字去延迟查询
ps:你这个过程实际上已经快接近正式项目架构师的方向了,当然我可以提出另外一个问题看看你能否自己推论一下如何解决
你的架构描述很不错,但是他能解决单个StudentInfo实例的表达,但是如果是 List<StudentInfo>呢,每个StudentInfo都单独去查一次表??1000个元素地StudentInfo列表就要查1000次表?? 很明显这个方案在实际使用上是符合业务逻辑,但是却缺乏性能上地考虑
#9
#10
这个也是我最近在苦恼的,虽然单个实体的问题解决了,但对于统计类的问题,就不好解决,而对于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
http://www.cnblogs.com/xishuai/p/3691787.html
#14
两个问题。最重要地,“实体”根本跟数据库没有直接关系。实体是用来在各个层次之间进行通讯的,它只作基本的“内存中的”数据处理。逻辑层会对数据库“增删改查”,那能跑到实体类里边去读取数据库的?
作为一个低级的“技术”问题,如果你想得到ICollection<T>,可以使用Linq的ToList()方法,得到的集合就具有那个接口。
#15
如果你对
CetInfo= from s in db.RegTab
where s.Xh == studID
select s;
不满意,你应该使用一个BLL功能方法来封装更有意义的查询操作,而不是乱改什么实体定义。
我确实遇到过自称为研究了“三层”6、7年的人在实体类里乱写数据库查询,这样的人基本上都改行做销售了,而没有做出什么产品。因为一旦做灵活一点的东西,过度单一的模型让他就根本纠结不清了。
CetInfo= from s in db.RegTab
where s.Xh == studID
select s;
不满意,你应该使用一个BLL功能方法来封装更有意义的查询操作,而不是乱改什么实体定义。
我确实遇到过自称为研究了“三层”6、7年的人在实体类里乱写数据库查询,这样的人基本上都改行做销售了,而没有做出什么产品。因为一旦做灵活一点的东西,过度单一的模型让他就根本纠结不清了。
#16
封装操作我明白了,确实不应该放在这个地方,因为我这个是测试代码,还在实验中,所以暂时放这里了,你的建议很好,但我仍然很纠结,这个功能或者方法应该放哪里呢?
不过我现在纠结的不是这个方法放哪里,而是查询出来的类型和实体的类型不匹配。或者说我还是没有真正理解实体与数据库的关系?
又或者这个查询应该在底层查询的时候就将类型转换过来?
#17
大哥,有没有一个例子给我看下,学习一下。
我实在是想不清楚啊。
我实在是想不清楚啊。
#18
另外,我这个不是三层结构啊。
底层是EF,再上一层是对EF进行操作的层,中间是业务实体,这一层才是真正的现实世界的对象,再往上业务层,再往上是表现层。
现在我卡在中间这个业务实体层了,根源在于操作EF出来的结果,并不是真正的业务对象,但是这业务实体层比EF操作层要高一层,又不能在里面用业务实体层。郁闷的很。
也请高手们看下,我这样分层对不对。
底层是EF,再上一层是对EF进行操作的层,中间是业务实体,这一层才是真正的现实世界的对象,再往上业务层,再往上是表现层。
现在我卡在中间这个业务实体层了,根源在于操作EF出来的结果,并不是真正的业务对象,但是这业务实体层比EF操作层要高一层,又不能在里面用业务实体层。郁闷的很。
也请高手们看下,我这样分层对不对。