关于NopCommerce的EF使用

smartslap 2011-07-12 04:49:18
NopCommerce里面取消了工具生成实体,用了自定义实体类。
而手写代码的实体中,有自定义属性,而把跟自定义属性功能差不多的导航属性删除了,这是为什么?

这是自定义属性:

public List<StateProvince> StateProvinces
{
get
{
return IoC.Resolve<IStateProvinceService>().GetStateProvincesByCountryId(this.CountryId);
}
}


这是导航属性:

public virtual ICollection<StateProvince> NpStateProvinces { get; set; }


实际上这两个的功能是一样的,但NopCommerce的大多数地方都删除了导航属性,而使用的自定义属性。
...全文
497 9 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
smartslap 2011-07-24
  • 打赏
  • 举报
回复
感觉不是太明白,可能欠缺一些理解这些知识的基础。还是先结帖吧,留待以后再思考。
阿非 2011-07-19
  • 打赏
  • 举报
回复
应该说是通过 Properties (属性) 来实现的 lazy load (延迟加载)

Properties 本身就是个语法糖,最后会编译成方法的

缓存和延迟加载没有必然的联系,适当的应用缓存可以提高性能。


用 virtual 修饰的 Properties ,你可以写个类派生自相关类。 然后 override 该 Properties 即可
smartslap 2011-07-17
  • 打赏
  • 举报
回复
看了下NopCommerce的.edmx,它关闭了延迟加载。这样的话,任何一个查询都会隐式地把导航属性加载进来。
而NopCommerce的POCO对象删除了导航属性,所以在查询某个对象的时候,不会加载该对象的导航属性。

通过使用自定义属性,就可以实现延迟加载一样的效果。

NopCommerce在查询数据的时候,使用自定义属性(因为导航属性已经被删除了,所以不可能通过导航属性来获得所需数据),自定义属性调用的方法又查看了缓存有没有所需数据,如果有所需数据就不需要访问数据库了,如没有缓存再查数据库得到所需数据。

举个例子:
1. 国家的省份是1:n的关系,所以省份的对象中,应该包含一个指向其所属国家的导航属性:
public virtual Country NpCountry { get; set; }

而NopCommerce删除了这个导航属性,而添加了一个自定义的Country属性。

public Country Country
{
get
{
return IoC.Resolve<ICountryService>().GetCountryById(this.CountryId);
}
}


2. 当我们想要查询这个省份所属国家的时候,使用以下语句:

Country country = stateProvince.Country;

调用了Country自定义属性的Get,而Get里面用到了这个方法:GetCountryById(this.CountryId)
看看这个方法的代码:

public Country GetCountryById(int countryId)
{
if (countryId == 0)
return null;

//如果被缓存的话,就从缓存里面取。
string key = string.Format(COUNTRIES_BY_ID_KEY, countryId);
object obj2 = _cacheManager.Get(key);
if (this.CacheEnabled && (obj2 != null))
{
return (Country)obj2;
}

//如果没有被缓存,就从数据库里面查询。
var query = from c in _context.Countries
where c.CountryId == countryId
select c;
var country = query.SingleOrDefault();

if (this.CacheEnabled)
{
_cacheManager.Add(key, country);
}
return country;
}


通过以上代码我得出的结论:NopCommerce通过 自定义属性实现了延迟加载和缓存机制。

不知道我的看法对不对?
smartslap 2011-07-17
  • 打赏
  • 举报
回复
我只知道virtual修饰的导航属性是EF内部生成的继承类使用的,不知道自己应该如何重写这个属性。
所以在我们没有重写导航属性的情况下,按照EF延迟加载的处理方式,使用这个导航属性应该是要查数据库的吧?
阿非 2011-07-17
  • 打赏
  • 举报
回复
如果指定了EF使用延迟加载,是不是通过导航属性取得的数据,都需要查数据库?
--------------------------------
不是的,virtual 修饰 你在派生类中可以覆写,具体的做法可以由你指定

而通过自定义属性,就可以根据设置选择是查数据库还是从缓存里面取?
-----------------------------------------
不是设置,而是程序编译前 已经写死在代码中了,灵活性没有virtual 的高,但同事复杂度也要低

查数据库还是缓存是在IoC.Resolve<IStateProvinceService>().GetStateProvincesByCountryId

这里写的



为了能从缓存里面取数据,所以NopCommerce的POCO对象使用自定义属性,而删除了导航属性?
------------------------------------------------------
不是这个原因,应该有 convention over configuration 的考虑
smartslap 2011-07-17
  • 打赏
  • 举报
回复
确实IoC.Resolve<IStateProvinceService>().GetStateProvincesByCountryId(this.CountryId)这个方法指定了从缓存里面取数据。

如果指定了EF使用延迟加载,是不是通过导航属性取得的数据,都需要查数据库?
而通过自定义属性,就可以根据设置选择是查数据库还是从缓存里面取?

也就是说,为了能从缓存里面取数据,所以NopCommerce的POCO对象使用自定义属性,而删除了导航属性?
阿非 2011-07-17
  • 打赏
  • 举报
回复
virtual 修饰,表明可由派生类来覆写

具体做法我不了解,猜测可能是由容器来指定派生类从而懒加载或一次性加载。

这样的话,灵活性有但复杂度也有。

get
{
return IoC.Resolve<IStateProvinceService>().GetStateProvincesByCountryId(this.CountryId);
}

这个也是懒加载的

也可以设置相关对象的缓存的

IoC.Resolve<IStateProvinceService>() 这里

和GetStateProvincesByCountryId(this.CountryId)这里
smartslap 2011-07-16
  • 打赏
  • 举报
回复
导航属性是受Context管理的,会延迟加载或一次性加载。
而这个自定义属性必然会在Get的时候查数据库。

从这些方面考虑,NopCommerce的作者应该是怎么想的呢?
子夜__ 2011-07-13
  • 打赏
  • 举报
回复
没有注意过这个。。。

62,242

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术交流专区
javascript云原生 企业社区
社区管理员
  • ASP.NET
  • .Net开发者社区
  • R小R
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

.NET 社区是一个围绕开源 .NET 的开放、热情、创新、包容的技术社区。社区致力于为广大 .NET 爱好者提供一个良好的知识共享、协同互助的 .NET 技术交流环境。我们尊重不同意见,支持健康理性的辩论和互动,反对歧视和攻击。

希望和大家一起共同营造一个活跃、友好的社区氛围。

试试用AI创作助手写篇文章吧