Castle Active Record - 对象引用未保存的瞬态实例

时间:2011-11-02 14:03:32

标签: nhibernate configuration castle-activerecord

嗨,这是我第一次使用Active Record我尝试使用官方网站上的教程。

首先我创造了一些优势:

[ActiveRecord("Users")]
public class User : ActiveRecordBase<User>
{
    private IList<PhotoAlbum> _albums = new List<PhotoAlbum>();

    [PrimaryKey]
    public virtual int UserId { get; set; }

    [BelongsTo("ProfilId")]
    public virtual Profil Profil { get; set; }

    [HasMany(typeof(PhotoAlbum),Table = "PhotoAlbums",
        ColumnKey = "UserId", 
        Cascade = ManyRelationCascadeEnum.AllDeleteOrphan)]
    public IList<PhotoAlbum> Album
    {
        get { return _albums; }
        set { _albums = value; }
    }

    [Property]
    public virtual string AzetId { get; set; }
    [Property]
    public virtual string Nick { get; set; }
    [Property]
    public virtual string SelfNick { get; set; }
}

[ActiveRecord("Profiles")]
public class Profil : ActiveRecordBase<Profil>
{
    [PrimaryKey]
    public int ProfilId { get; set; }

    [Property]
    public int Age { get; set; }
    [Property]
    public int Sex { get; set; }
    [Property]
    public string Region { get; set; }
    [Property]
    public string Town { get; set; }
    [Property]
    public bool WithPhoto { get; set; }
    [Property]
    public bool HasPhotoAlbum { get; set; }
}

[ActiveRecord("PhotoAlbums")]
public class PhotoAlbum : ActiveRecordBase<PhotoAlbum>
{
    [PrimaryKey]
    public int PhotoAlbumId { get; set; }

    [Property]
    public string Name { get; set; }
    [Property]
    public int NumberOfPhoto { get; set; }
}

然后我为活动记录创建了xml配置文件:

<activerecord>
  <config>
    <add
      key="hibernate.connection.driver_class"
      value="NHibernate.Driver.SqlClientDriver" />
    <add
      key="dialect"
      value="NHibernate.Dialect.MsSql2008Dialect" />
    <add
      key="connection.provider"
      value="NHibernate.Connection.DriverConnectionProvider" />
    <add
      key="connection.connection_string"
      value="Data Source=test\sqlexpress;Initial Catalog=TEST_AR_POKEC;Integrated Security=SSPI" />
  </config>

</activerecord>

Finnaly我测试过:

    public static User GetUser(string nick, int sex,
        string loc)
    {
        return new User
        {
            AzetId = new Random().Next()
            .ToString(),
            Nick = nick,
            SelfNick = nick.ToUpper(),
            Profil = new Profil()
            {
                Sex = sex,
                Region = loc,
                WithPhoto = true,
                Age = new Random().Next(6, 99),
                HasPhotoAlbum = true,
                Town = loc
            },
            Album = new List<PhotoAlbum>
                                         {
                                             new PhotoAlbum
                                                 {
                                                     Name = "Me",
                                                     NumberOfPhoto =new Random().Next()
                                                 }
                                         }

        };
    }


        var source = new XmlConfigurationSource("ac.xml");

        ActiveRecordStarter.Initialize(source,typeof(Profil),typeof(PhotoAlbum), typeof(User));
        ActiveRecordStarter.CreateSchema();

        var user = GetUser("tom",1,"DC");
        user.Create();

完成了这个错误:

  

未配置ProxyFactoryFactory。初始化   会话工厂的'proxyfactory.factory_class'属性   配置部分,其中一个可用的NHibernate.ByteCode   提供者。

我谷歌它,我想我发现aswer我修改了xml配置为活动记录我添加了这部分:

 <add
      key="proxyfactory.factory_class"
      value="NHibernate.ByteCode.Castle.ProxyFactoryFactory, NHibernate.ByteCode.Castle"/>

我再次测试了。它在数据库中创建了表格,但是没有将数据插入表格,我收到了这个错误:

  

对象引用未保存的瞬态实例 - 保存瞬态   冲洗前的实例。

这是StackTrace:

  

在   NHibernate.Engine.ForeignKeys.GetEntityIdentifierIfNotUnsaved(字符串   entityName,Object entity,ISessionImplementor session)at   NHibernate.Type.EntityType.GetIdentifier(对象值,   ISessionImplementor会议)   NHibernate.Type.ManyToOneType.IsDirty(对象旧,对象当前,   Boolean [] checkable,ISessionImplementor session)at   NHibernate.Type.TypeHelper.FindDirty(StandardProperty []属性,   Object [] currentState,Object [] previousState,Boolean [] []   includeColumns,Boolean anyUninitializedProperties,   ISessionImplementor会议)   NHibernate.Persister.Entity.AbstractEntityPersister.FindDirty(对象[]   currentState,Object [] previousState,Object entity,   ISessionImplementor会议)   NHibernate.Event.Default.DefaultFlushEntityEventListener.DirtyCheck(FlushEntityEvent   事件)   NHibernate.Event.Default.DefaultFlushEntityEventListener.IsUpdateNecessary(FlushEntityEvent   event,Boolean mightBeDirty)at   NHibernate.Event.Default.DefaultFlushEntityEventListener.OnFlushEntity(FlushEntityEvent   事件)   NHibernate.Event.Default.AbstractFlushingEventListener.FlushEntities(FlushEvent   事件)   NHibernate.Event.Default.AbstractFlushingEventListener.FlushEverythingToExecutions(FlushEvent   事件)   NHibernate.Event.Default.DefaultFlushEventListener.OnFlush(FlushEvent   事件)在NHibernate.Impl.SessionImpl.Flush()at   Castle.ActiveRecord.Framework.SessionFactoryHolder.ReleaseSession(的Isession   会议)在   Castle.ActiveRecord.ActiveRecordBase.InternalCreate(对象实例,   布尔刷新)   Castle.ActiveRecord.ActiveRecordBase.Create(对象实例)at   Castle.ActiveRecord.ActiveRecordBase.Create()at   EAMPLE中的SAMPLE_1.Program.Main(String [] args)#C#   PROJECTS \ STUDY \ STUDY.ORM \ Active Record \ SAMPLE_1 \ Program.cs:第51行   在System.AppDomain._nExecuteAssembly(RuntimeAssembly程序集,   System.AppDomain.ExecuteAssembly上的String [] args)(String   assemblyFile,Evidence assemblySecurity,String [] args)at   Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
  在System.Threading.ThreadHelper.ThreadStart_Context(对象状态)
  在System.Threading.ExecutionContext.Run(ExecutionContext   executionContext,ContextCallback回调,对象状态,布尔值   ignoreSyncCtx)at   System.Threading.ExecutionContext.Run(执行上下文   executionContext,ContextCallback回调,对象状态)at   System.Threading.ThreadHelper.ThreadStart()

也许问题在这里:

[BelongsTo("ProfilId")]
public virtual Profil Profil { get; set; }

[HasMany(typeof(PhotoAlbum),Table = "PhotoAlbums",
    ColumnKey = "UserId", 
    Cascade = ManyRelationCascadeEnum.AllDeleteOrphan)]
public IList<PhotoAlbum> Album
{
    get { return _albums; }
    set { _albums = value; }
}

我不确定,但如果我省略了这两个属性(关系),它就可以正常工作并将数据插入到表中。但是由于关系不起作用。

编辑:

如果我指定Cascade行为它可以工作......但为什么?

   [BelongsTo("ProfilId", 
        Cascade =CascadeEnum.All)]
    public virtual Profil Profil { get; set; }

    [HasMany(typeof(PhotoAlbum), 
        Table = "PhotoAlbums",
        ColumnKey = "UserId",
        Cascade = ManyRelationCascadeEnum.All)]
    public IList<PhotoAlbum> Album
    {
        get { return _albums; }
        set { _albums = value; }
    }

1 个答案:

答案 0 :(得分:0)

如果您不希望Profile自动与User对象一起保存CascadeEnum.All,则必须在保存User之前在会话中单独保存此对象。

在级联未启用时抛出该异常的原因是因为Profile中的User对象为transient(未保存)。如果您启用级联,它会自动保存您的对象,因此不是transient

级联

的示例
ISession.Save(user);

没有级联的示例

ISession.Save(profile);
Isession.Save(user);