我有一段时间试图找出NHibernate中的会话管理问题.我假设我的很多麻烦都是由于缺乏对IoC和AOP概念的了解; 至少那是我在思考Fabio Maulo指导我的地方.
无论如何,我的问题是我有一个win表单应用程序正在进行"get"调用并将结果绑定到网格.在绑定之后,用户可以执行某种"写入"动作,并且这些动作导致在写入之后会话被关闭以尝试使用每次使用会话的概念.然后用户可以滚动网格,这导致延迟加载开始,现在会话已经关闭,我得到一个例外.
我不想让我的观点认识到我的会话,我不想在用户关闭表单时发送KillAllSessions.此外,用户可以在任何给定时间打开多个表单,从而进一步加剧与该方法相关的问题.我基本上希望所有这些都能在"幕后"工作.
所以到目前为止我的想法是拦截延迟加载调用并检查会话是否打开,如果没有重新打开它,获取信息然后重新关闭它.但是,据我所知,这并不多,这本质上就是延迟加载的工作原理.它被代理工厂(NHibernate.Bytecode.Castle)拦截,然后使用会话检索数据.所以我需要实际拦截该调用,然后在重新打开会话后将其传递给原始的预期拦截.这就是我的想法.
我的问题基本上首先是这个甚至是正确的方法吗?第二,如果它是我甚至不知道从哪里开始.我从未对方法调用进行任何拦截,我在理论上知道但在实践中却没有.我知道有些图书馆可以做Rhino Commons这样的事情,但我想利用这个机会学习并成为一名更好的程序员.我正在尝试理解AOP和Context Bound Objects,但目前我并没有理解它.你们有些人可以帮助一个人吗?
我的情况是我搞砸了.大约1.5年前,当我采用这个位置而不是重新发明轮子时,我继承了我的代码库,尽管我现在知道我应该拥有,但我保持DAL与之前的开发人员几乎完全相同.
基本上有一个文件(现在是15k行代码),用作一堆使用DataSet和TableAdapter来检索数据的DAO.我的xsd文件已经发展到这样的大小,每次打开时它们都会导致R#崩溃视觉工作室,而现在15k行的中间类也需要永远让R#进行分析.更不用说它是丑陋的,它可以工作,但不是很好,并且是调试的绝对噩梦.
到目前为止我尝试过的是切换到NHibernate.NHibernate是一个很棒的库,但不幸的是它不适应我的应用程序,从主要的开发人员说(Fabio Maulo)它几乎是我的应用程序要求和NHibernate在使用身份作为数据库时的限制的组合PK战略.
所以现在我回到基本上设计我自己的DAL.我正在考虑一些不同的模式,但是想获得你的DAL设计策略.有很多方法和理由以特定的方式实施DAL,所以如果你能解释你的策略以及为什么它最适合你,我将非常感激.
提前致谢!
编辑:让我解释为什么NHibernate没有工作,因为这似乎是立即响应.我的用户创建了一个"作业",它实际上只是我的Job类的瞬态表示.在这项工作中,他们将给出一个或一个在创建时也是短暂的权重因子列表.最后,他们提供了一个工作细节列表,这些细节具有与之相关的特定权重因子.因为,在DB中,当我继续工作时权重因子是唯一的,并且当它找到重复的权重因子时,它会降低到权重因子.我尝试在将权重因子分配给详细信息之前运行检查(我不想这样做,因为我不想对数据库进行额外调用)但在NH中调用CreateCriteria也会导致会话中的刷新,根据Fabio,它会破坏我的缓存,从而杀死整个作业的内存表示.NH邮件列表上的人说我应该切换到GUID,但这不是一个可行的选择,因为转换过程将是一场噩梦.
我借用了一个查询并根据自己的目的进行了调整,但是当我不完全确定它在做什么时,我不喜欢这样做.SQL文档对此子句的描述不够.这是我借用和修改的内容,你能告诉我它基本上在做什么吗?
(SELECT Id FROM
(
SELECT
Id
,RANK() OVER ( PARTITION BY DropStatusId ORDER BY StatusDate DESC) [Rank]
FROM
[dbo].[tblLHTrackingHistory] [TempHistory]
WHERE
[TempHistory].[DropStatusId] = [DropStatus].[Id]
) [TT1] WHERE [Rank] = 1
)
Run Code Online (Sandbox Code Playgroud) 我试图在运行时派生一个对象的类型.具体来说,无论是实现ICollection还是IDto,我都需要知道两件事.目前我能找到的唯一解决方案是:
private static bool IsACollection(PropertyDescriptor descriptor)
{
bool isCollection = false;
foreach (Type type in descriptor.PropertyType.GetInterfaces())
{
if (type.IsGenericType)
{
if (type.GetGenericTypeDefinition() == typeof(ICollection<>))
{
isCollection = true;
break;
}
}
else
{
if (type == typeof(ICollection))
{
isCollection = true;
break;
}
}
}
return isCollection;
}
private static bool IsADto(PropertyDescriptor descriptor)
{
bool isDto = false;
foreach (Type type in descriptor.PropertyType.GetInterfaces())
{
if (type == typeof(IDto))
{
isDto = true;
break;
}
}
return isDto;
}
Run Code Online (Sandbox Code Playgroud)
但我相信必须有一个比这更好的方法.我尝试过以正常方式比较,例如:
if(descriptor.PropertyType …
Run Code Online (Sandbox Code Playgroud) 我有一个WinForms应用程序,我希望将重构为使用DDD架构.首先,我试图真正地围绕建筑本身,我有埃文斯的书,我有弗农的书,我发现自己正在努力应对我将面临的三个场景.我担心在概念设计过程中我可能会过度思考或过于严格.
1.)利用DDD的Pluralsight教程中提供的示例,发言者指出不同的有界上下文应该由他们自己的解决方案来表示.但是,如果我有一个不面向服务的winforms应用程序(这最终会改变并且很多问题变得毫无意义)这似乎不可行.因此,我假设我将把它们分成不同的项目/名称空间,保持警惕没有相互依赖性.这是考虑它的正确方法还是我错过了一些明显的东西?
2.)我有一个导航UI,它启动其他模块/窗口,这些模块/窗口属于不同有界上下文的单独表示层.想想在启动ERP应用程序时打开的第一个窗口.由于这不适合任何特定的BC,如何正确实现这样的事情.这应该属于共享内核吗?
3.)我有一个工作管理有限的背景和评级/成本计算有限的背景.创建作业时,业务流程的一部分是对其详细信息进行评级.这有自己的UI等,我觉得这个演示文稿仍然充分属于作业管理环境.但是,这些细节的实际评级过程绝对不应该.我不完全确定如何与评级/成本核算相关联,因为bc要彼此分开.我意识到我可以做消息传递,但对于非分布式应用来说,这似乎有些过分.每个BC都可以自己托管某种API,但这似乎有点过分,尽管这会让团队很好地在以后迁移到分布式架构.最后,我的最后一个想法是拥有某种共享依赖,这是一种各种事件存储.我不知道这是否与Domain Events相同,因为它们本身似乎有一个单独的问题.那么,这是否意味着这将属于共享内核或其他类型的解决方案?
先感谢您.
这是我的自定义集合声明.
public interface IMenuCollection<T> : ICollection<T>
public class HTMLMenuCollection: IMenuCollection<HTMLMenu>
Run Code Online (Sandbox Code Playgroud)
我试图从另一个集合中转向它IList<T>
.
IList<HTMLMenu> htmlMenuList = new List<HTMLMenu>();
...
HTMLMenuCollection tempColl = (HTMLMenuCollection)htmlMenuList;
Run Code Online (Sandbox Code Playgroud)
我不知道为什么这不起作用.如果我投射IList<T>
到ICollection<T>
它工作得很好,但有了这个我得到一个无效的强制转换异常.我究竟做错了什么?
我在SQL Server 2005中有这个查询:
SELECT J.JobID,
dbo.tblCustomers.Name AS CustomerName,
J.CustomerJobNumber,
J.JobName,
(CASE WHEN [tblCustomers].[CoreCust] = 0 THEN 'AUXILIARY' ELSE 'CORE' END) AS Department,
J.JobStatusID,
dbo.tblJobTypes.JobType
FROM dbo.tblJobs (NOLOCK) AS J
INNER JOIN dbo.tblCustomers (NOLOCK) ON J.CustomerID = dbo.tblCustomers.CustomerID
INNER JOIN dbo.tblJobTypes (NOLOCK) ON J.JobTypeID = dbo.tblJobTypes.JobTypeID
INNER JOIN dbo.tblDepartments (NOLOCK) ON J.DepartmentId = dbo.tblDepartments.DepartmentID
WHERE (J.Closed = 0)
AND (J.Invoiced = 0)
AND (J.Active = 1)
AND (dbo.fncIsAllPointsDelivered(J.JobID) = 1)
AND (J.DepartmentId <> 2)
Run Code Online (Sandbox Code Playgroud)
这个查询运行时间太长,我知道问题是UDF - (dbo.fncIsAllPointsDelivered(J.JobID)= 1) - .
UDF的SQL在这里: …
c# ×4
database ×2
sql ×2
sql-server ×2
t-sql ×2
.net ×1
architecture ×1
c#-2.0 ×1
casting ×1
collections ×1
exception ×1
generics ×1
interceptor ×1
lazy-loading ×1
nhibernate ×1
reflection ×1
session ×1
winforms ×1