1

我正在使用带有 NHibernate 3.3.2.4000 的 Oracle 数据库。

我设置了一个单元测试来验证是否可以从表中选择实体集合。这是它的样子:

[TestFixture]
public class UnitOfWorkIntegrationTests
{
    private IUnitOfWork _unitOfWork;
    private INHibernateSessionFactory _nHibernateSessionFactory;
    private IActiveSessionManager _activeSessionManager;

    [SetUp]
    public void BeforeEachTest()
    {
        _nHibernateSessionFactory = new NHibernateSessionFactory();
        _activeSessionManager = new ActiveSessionManager();
        _unitOfWork = new UnitOfWork(_nHibernateSessionFactory, _activeSessionManager);
    }

    [Test]
    public void ShouldFetchOAuthMemberships()
    {
        var oauths = _unitOfWork.OAuthMemberships.ToArray();
        oauths.ShouldNotBeNull();
    }
}

获取我的 OAuthMemberships 集合的行抛出了这个异常:

无法执行查询

[从 bckgrd_booklet_app.OAuthMembership oauthmembe0_ 中选择 oauthmembe0_.id 作为 id13_]

[SQL: select oauthmembe0_.id as id13_ from bckgrd_booklet_app.OAuthMembership oauthmembe0_]

我的 OAuthMembership 类和映射如下。如您所见,我将表名定义为“OAUTH_MEMBERSHIP”,但生成的 SQL 包含驼峰式类名。我没有定义表名约定。为什么 NHibernate 会忽略我的 Oracle 大小写表名?

public class OAuthMembership
{
    public virtual int Id { get; set; }
    public virtual string Provider { get; set; }
    public virtual string ProviderUserId { get; set; }

    public virtual UserProfile UserProfile { get; set; }
}

public class OAuthMembershipMap : ClassMapping<OAuthMembership>
{
    public void OAuthMembership()
    {
        Table("OAUTH_MEMBERSHIP");

        Id(x => x.Id, m => m.Column("ID"));
        Property(x => x.Provider, m => m.Column("PROVIDER"));
        Property(x => x.ProviderUserId, m => m.Column("PROVIDER_USER_ID"));
        
        ManyToOne(x => x.UserProfile, m => m.Column("USER_PROFILE_ID"));
    }
}

这是我的 NHibernateSessionFactory:

public interface INHibernateSessionFactory
{
    ISession Create();
}

public class NHibernateSessionFactory : INHibernateSessionFactory
{
    private static readonly ILog Log = LogManager.GetLogger(typeof(NHibernateSessionFactory).Name);
    private readonly static ISessionFactory SessionFactory;
    public static string ConnectionString
    {
        get
        {
            return ConfigurationManager.ConnectionStrings["MyConnection"].Return(x => x.ConnectionString,
                "Data Source=myServer;User ID=bckgrd_booklet_app;Password=myPass;");
        }
    }

    static NHibernateSessionFactory()
    {
        try
        {
            var mapper = new ModelMapper();
            mapper.AddMappings(Assembly.GetExecutingAssembly().GetExportedTypes());

            HbmMapping domainMapping = mapper.CompileMappingForAllExplicitlyAddedEntities();

            var configure = new NHibernate.Cfg.Configuration().Configure();
            configure.AddMapping(domainMapping);
            configure.BuildMappings();
            configure.DataBaseIntegration(x =>
            {
                x.Driver<OracleClientDriver>();
                x.Dialect<Oracle10gDialect>();
                x.ConnectionStringName = ConnectionString;
            })
            .CurrentSessionContext<WebSessionContext>();
            SessionFactory = configure.BuildSessionFactory();

        }
        catch (Exception ex)
        {
            Log.Error("NHibernateSessionFactory did not initialize correctly.", ex);
            throw;
        }
    }

    public ISession Create()
    {
        Log.Debug("Creating new session.");
        return SessionFactory.OpenSession();
    }
}

我的 ActiveSessionManager:

public interface IActiveSessionManager
{
    void ClearActiveSession();
    NHibernate.ISession GetActiveSession();
    void SetActiveSession(NHibernate.ISession session);
}

public class ActiveSessionManager : IActiveSessionManager
{
    [ThreadStatic]
    private static ISession _current;

    public ISession GetActiveSession()
    {
        return _current;
    }

    public void SetActiveSession(ISession session)
    {
        _current = session;
    }

    public void ClearActiveSession()
    {
        _current = null;
    }
}

我的 UnitOfWork 定义的相关部分:

public interface IUnitOfWork
{
    //...
    IQueryable<OAuthMembership> OAuthMemberships { get; }
    IQueryable<T> All<T>();
    //...
}

public class UnitOfWork : IUnitOfWork
{
    private readonly ISession _session;

    //...

    public IQueryable<OAuthMembership> OAuthMemberships
    {
        get { return All<OAuthMembership>(); }
    }

    public UnitOfWork(
        INHibernateSessionFactory sessionFactory,
        IActiveSessionManager activeSessionManager)
    {
        _session = sessionFactory.Create();
        activeSessionManager.SetActiveSession(_session);
    }

    public IQueryable<T> All<T>()
    {
        return _session.Query<T>();
    }

    //...
}
4

1 回答 1

1

在将 Fluent NHibernate 添加到我的项目并在那里犯了同样的错误后,我发现了我的错误。

我的 OAuthMembershipMap 没有构造函数。我错误地添加了一个名为 OAuthMembership 的 void 方法,因此我的表映射以及我的 Id 和 Property 映射失败。请参阅更正后的代码:

public class OAuthMembershipMap : ClassMapping<OAuthMembership>
{
    public OAuthMembershipMap()
    {
        Table("OAUTH_MEMBERSHIP");

        Id(x => x.Id, m => m.Column("ID"));
        Property(x => x.Provider, m => m.Column("PROVIDER"));
        Property(x => x.ProviderUserId, m => m.Column("PROVIDER_USER_ID"));

        ManyToOne(x => x.UserProfile, m => m.Column("USER_PROFILE_ID"));
    }
}
于 2012-12-04T16:40:52.427 回答