为什么NHibernate按代码映射会忽略我的Oracle表名:

时间:2012-12-03 21:38:52

标签: oracle nhibernate mapping-by-code

我正在使用带有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:从bckgrd_booklet_app.OAuthMembership oauthmembe0 _选择oauthmembe0_.id为id13_]

我的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>();
    }

    //...
}

1 个答案:

答案 0 :(得分: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"));
    }
}