我正在写一个博客引擎作为学习练习.我知道那里有很多博客引擎,但请耐心等待......
我有一个BlogPost实体,它有一个属性标签,它是与之关联的标签的IList.BlogPost.SetTags(string)方法拆分字符串,使用指定的标记名称创建新的Tag对象,并将它们添加到列表中.BlogPost.AddTag(字符串tagName)也是如此.
我想要发生的是,当我调用BlogPost.AddTag("foo"),其中一个名为"foo"的标签实体已经存在并且在数据库中持久存在时,nHibernate只是意识到这一点,并用现有标签连接帖子.
在BlogRepository.Save()方法中,我检查标签列表中的每个标签是否已经存在.如果没有,我通过调用TagRepository.Save(tag)保存它;
问题是,在下面的示例代码中,我收到一个错误"NHibernate.NonUniqueObjectException:具有相同标识符值的另一个对象已经与会话关联:标记1,实体:CMS.Core.Model.Tag"当我尝试使用现有标记持久保存BlogPost对象时.当我坚持只使用新标签的BlogPost对象时,它们就被创建了,一切都很好.
注意我还使用TagName作为bp_Tags表的数据库中的主键.当表只存储唯一的Tag名称时,使用整数或GUID PK似乎是多余的.
我的nHibernate配置如下:
<class name="CMS.Core.Model.Tag,CMS.Core" table="bp_Tags">
<id column="TagName" name="TagName" type="String" unsaved-value="">
<generator class="assigned" />
</id>
</class>
<class name="CMS.Core.Model.BlogPost,CMS.Core" table="bp_Content">
<id name="Id" column="Id" type="Int32" unsaved-value="0">
<generator class="native"></generator>
</id>
<property name="SubmittedBy" column="SubmittedBy" type="string" length="256" not-null="true" />
<property name="SubmittedDate" column="SubmittedDate" type="datetime" not-null="true" />
<property name="PublishDate" column="PublishDate" type="datetime" not-null="true" />
...
<bag name="_tagsList" table="bp_Tags_Mappings" lazy="false" cascade="all">
<key column="Target_Id" />
<many-to-many class="CMS.Core.Model.Tag,CMS.Core" column="TagName" lazy="false" />
</bag>
Run Code Online (Sandbox Code Playgroud)
NHibernate.NonUniqueObjectException:具有相同标识符值的不同对象已与会话关联:标记1,实体:Bariliant.CMS.Core.Model.Tag
BlogPost post, post2;
using (UnitOfWork.Start())
{
post = BlogPostFactory.CreateBlogPost("test post", "test body");
post.Publish(); …Run Code Online (Sandbox Code Playgroud) 我正在寻找一些基于ASP.NET MVC的CMS应用程序架构的反馈.
域模型 - 除了System类之外什么都不依赖于定义类型.目前,大多贫血.
存储库层 - 抽象数据访问,仅由服务层调用
服务层 - 在域模型上执行业务逻辑.将视图模型暴露给控制器.
ViewModelMapper - 在视图模型和域模型之间来回转换的服务
控制器 - 超薄"交通警察"风格功能,与服务层交互,仅根据视图模型进行讨论,从不进行域模型
我的域模型主要用作数据传输(DTO)对象,目前逻辑很少.我发现这很好,因为它取决于什么(甚至不是服务层中的类).
服务层有点棘手......我只希望控制器能够访问视图模型以便于GUI编程.但是,有些服务需要相互通信.例如,我有一个事件服务,在标记内容,创建博客帖子等时通知其他侦听器服务.目前,将域模型作为输入或返回它们的方法标记为内部,因此它们不能被控制器.
听起来有点矫枉过正?抽象不够?我主要是将这作为一种严格的建筑学习而不是实际产品的学习练习,所以请不要按照"正确取决于你想做什么"的方式做出反馈.
谢谢!