我正在设计一个ASP.NET MVC3应用程序,我希望在3层架构中明确区分关注点.我使用Fluent NHibernate作为ORM,Repository模式与NHibernate映射的实体一起使用.我想添加一个具有Unit Of Work模式的适当业务层,保留MVC部分仅用于表示(通过使用通过业务层映射到nHibernate实体的ViewModels). 本文很好地描述了组合的3层和MVC架构.
根据这个MVC +工作单元+存储库文章,我没有看到业务层的明显区别.工作单元类为每个存储库类型提供强类型的getter,它看起来适合业务层.但是,它暴露了一个Save方法,我认为它会转换为使用nHibernate的BeginTransaction和CommitTransaction方法.这引出了一些问题:
1)将事务控制暴露给MVC是一个好主意吗?交易控制应该在哪个阶段发生?在我看来,MVC不应该对交易负责,但如何避免这种情况?
2)是否应该有一些自动处理交易的方法? 此ActionFilter实现是半自动的,但事务控制显然位于MVC部分,而不是业务层.
3)UnitOfWork类与业务层类相同吗?
- 如果是这样,这是否意味着我们可以在其中添加自定义业务逻辑方法?
- 如果没有,我们是否将工作单元包含在包含业务逻辑方法的其他类中?
我感谢任何想法或例子.谢谢.
architecture asp.net-mvc design-patterns unit-of-work fluent-nhibernate
我做了一个小测试,启用惰性loading.optionsBuilder.UseLazyLoadingProxies().UseSqlServer(ConnectionString);
(使用 EF Core 2.1.4)
我循环浏览有和没有的仪器,这是我得到的结果
情况1
var instruments = db.instruments.OrderBy(t=>t.id).Include(t=>t.NavPro1).ThenInclude(t=>t.NavPro2).Take(200);
Run Code Online (Sandbox Code Playgroud)
案例2
var instruments = db.instruments.OrderBy(t=>t.id).Include(t=>t.NavPro1).ThenInclude(t=>t.NavPro2).Take(200);
Run Code Online (Sandbox Code Playgroud)
然后
foreach (var i in instruments)
{
var props = i.NavPro1;
foreach (var prop in props)
{
sbPrintGreeks.AppendLine(prop.NavPro2.Name + " - " + prop.id + " - " + prop.Value);
}
}
Run Code Online (Sandbox Code Playgroud)
无需延迟加载,只需 7 秒即可获取 100k 行
使用延迟加载需要 160 秒才能获取 3k 行。
可以做些什么来获得良好的性能?
我多次听说过hibernate中出现了几个问题(特别是在使用延迟加载时).哪些是最常见的,可以采取哪些措施?
我想添加一些实用程序方法来帮助避免遗留应用程序中的许多n + 1问题.
常见的模式是这样的:
select a.* /* over 10 columns */
from [table-A] a
where /* something */
Run Code Online (Sandbox Code Playgroud)
检索到ClassA记录实例的集合
然后,子实例是惰性检索的:
select b.* /* over 10 columns */
from [sub-table-B] b
where b.ParentId = @ClassA_ID
Run Code Online (Sandbox Code Playgroud)
这导致n + 1选择问题.大多数情况下,这不是一个主要问题,因为ClassA在不经常命中的页面上只检索了几个实例,但是在越来越多的地方,这个n + 1问题导致页面变得太慢,因为应用程序已经缩放.
我正在寻找替换此应用程序的现有数据访问代码的一部分,以便一起检索ClassA实例和ClassB实例.
我认为有三种方法可以做到:
1)ClassA像我们现在一样获取实例,然后ClassB在一个聚合调用中获取实例:
select b.*
from [sub-table-B] b
where b.ParentId in ( /* list of parent IDs */ )
Run Code Online (Sandbox Code Playgroud)
这是两个单独的DB调用,动态SQL的查询计划将不可缓存(由于ID列表).
2)ClassB使用子查询获取实例:
select b.*
from [sub-table-B] …Run Code Online (Sandbox Code Playgroud) 我在使用 Spring、Hibernate 和 JPA 的 Web 应用程序中遇到一些问题。问题是内存消耗非常高,随着时间的推移,内存消耗会增加,而且似乎永远不会减少。它们很可能源于 EntityManager 的错误使用。我已经四处寻找,但还没有找到确定的东西。
我们使用的 DAO 都扩展了以下 GenericDAO,其中注入了我们唯一的 EntityManager:
public abstract class GenericDAOImpl<E extends AbstractEntity<P>, P> implements
GenericDAO<E, P> {
@PersistenceContext
@Autowired
private EntityManager entityManager;
[...]
Run Code Online (Sandbox Code Playgroud)
使用通用 DAO 是因为它具有通过 ID 等获取实体的方法,这在所有约 40 个 DAO 中实现起来会很痛苦。
EntityManager 通过以下方式配置为 Spring bean:
<bean class="org.springframework.orm.jpa.JpaTransactionManager"
id="transactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
<tx:annotation-driven mode="aspectj"
transaction-manager="transactionManager" />
<bean
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"
id="entityManagerFactory">
<property name="persistenceUnitName" value="persistenceUnit" />
<property name="dataSource" ref="dataSource" />
</bean>
<bean id="entityManager" factory-bean="entityManagerFactory"
factory-method="createEntityManager" scope="singleton" />
Run Code Online (Sandbox Code Playgroud)
我认为最大的问题是使用这个共享的 EntityManager 来处理所有事情。在服务类中,我们对需要事务的方法使用@Transactional 注释。这会根据我读取的内容自动刷新 EntityManager,但与清除不同,所以我猜对象仍在内存中。
我们注意到每天都会在数据库中自动导入数据后内存会增加(大约 …
我想知道,以下哪个示例最适合在我的情况下关闭记录集对象?
1)
这个关闭循环内的对象,但在下一个移动时打开一个新对象.如果有1000条记录,则会打开一个对象1000次并关闭1000次.这就是我通常会做的事情:
SQL = " ... "
Set rs1 = conn.Execute(SQL)
While NOT rs1.EOF
SQL = " ... "
Set rs2 = conn.Execute(SQL)
If NOT rs2.EOF Then
Response.Write ( ... )
End If
rs2.Close : set rs2 = Nothing
rs1.MoveNext
Wend
rs1.Close : Set rs1 = Nothing
Run Code Online (Sandbox Code Playgroud)
2)
这个例子就是我想知道的.在循环结束之后保存对象闭包(rs2.close),是获得还是降低性能?如果有1000条记录,这将打开1000个对象但只关闭一次:
SQL = " ... "
Set rs1 = conn.Execute(SQL)
While NOT rs1.EOF
SQL = " ... "
Set rs2 = conn.Execute(SQL)
If NOT rs2.EOF Then
Response.Write ( ... )
End …Run Code Online (Sandbox Code Playgroud) 我有一个我觉得非常沉重的动作结果,所以我想知道如何优化它以便它获得更好的性能.此Web应用程序将同时由+ 100,000个用户使用.
现在我的Actionresult做了以下事情:
每次用户访问视图时,此4个函数都会触发.这就是为什么我认为这个Actionresult非常糟糕.
如何将以下内容添加到我的Actionresults中?
添加计时器来检索XML文件并将xml数据填充到DB,就像每10分钟一样,因此每次用户访问视图时都不会触发.每次用户访问站点时,唯一需要触发的功能是viewmodel绑定并返回模型.我怎么能做到这一点?
注意:
这是我的行动结果:
public ActionResult Index()
{
//Get data from xml url (This is the code that shuld not run everytime a user visits the view)
var url = "http://www.interneturl.com/file.xml";
XNamespace dcM = "http://search.yahoo.com/mrss/";
var xdoc = XDocument.Load(url);
var items = xdoc.Descendants("item")
.Select(item => new
{
Title = item.Element("title").Value,
Description = item.Element("description").Value,
Link = item.Element("link").Value,
PubDate = item.Element("pubDate").Value,
MyImage = (string)item.Elements(dcM + "thumbnail")
.Where(i => i.Attribute("width").Value …Run Code Online (Sandbox Code Playgroud) 实现了一对多关系,并且工作正常.
我的问题是当我运行以下查询时,如果该表有100个员工行,并且每个员工有2个部门.数据库查询被调用101次,因为对于每个员工来说它正在调用部门查询,完成调用所有100行需要很长时间,任何人都可以建议任何替代解决方案吗?
请参阅下面的详细信息
它正在调用的查询:
First query is : SELECT * FROM Employee e
Next 100 queries : SELECT * FROM DEPARTMENT d WHERE d.EmployeeId=?
Run Code Online (Sandbox Code Playgroud)
JPA数据库调用:
javax.persistence.Query query = em.createNamedQuery("SELECT * FROM Employee e", Employee.class);
return query.getResultList();
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.Id;
import javax.persistence.NamedNativeQueries;
import javax.persistence.NamedNativeQuery;
import javax.persistence.OneToMany;
import javax.persistence.Table;
@Entity
@Table(name = "EMPLOYEE")
public class Employee implements Serializable
{
@Id
@Column(name = "EmployeeId")
String employeeId;
@OneToMany(mappedBy = "employee", cascade = CascadeType.ALL, fetch = FetchType.EAGER)
private …Run Code Online (Sandbox Code Playgroud) 与任何其他框架一样,Hibernate强加了一些限制.一个非常受欢迎的面试问题是:
"你对Hibernate遇到了什么样的困难?"
例如:
问:你可以补充一下这个简单的清单吗?
PS 当你是Hibernate的新手时,我并不是说那些困难,现在不知道如何映射多对多.我的意思是在使用这个框架时,每个有经验的程序员面临的困难.
在 Laravel 5.2 应用程序中,我有三个模型:User,Role和Task. AUser与 multiple 相关联Roles,aRole与 multiple 相关联Tasks。因此,每个用户通过他们的角色与多个任务相关联。
我正在尝试通过他们的角色访问Tasks与 a 相关的所有内容User。
我的模型的相关部分如下所示:
class User extends Authenticatable
{
public function roles()
{
return $this->belongsToMany('App\Role');
}
public function tasks()
{
return $this->hasManyThrough('App\Task', 'App\Role');
}
}
class Role extends Model
{
public function tasks()
{
return $this->belongsToMany('App\Task');
}
public function users()
{
return $this->belongsToMany('App\User');
}
}
class Task extends Model
{
public function roles() …Run Code Online (Sandbox Code Playgroud) hibernate ×4
java ×4
asp.net-mvc ×2
c# ×2
jpa ×2
sql ×2
actionresult ×1
architecture ×1
asp-classic ×1
asp.net ×1
ef-core-2.1 ×1
eloquent ×1
laravel ×1
laravel-5 ×1
lazy-loading ×1
many-to-many ×1
object ×1
optimization ×1
orm ×1
performance ×1
php ×1
recordset ×1
spring ×1
unit-of-work ×1