使用 NHibernate 的 Web 服务中的“无法执行查询错误”

Posted

技术标签:

【中文标题】使用 NHibernate 的 Web 服务中的“无法执行查询错误”【英文标题】:"Could not execute query error" in Web Services with NHibernate 【发布时间】:2014-12-07 14:21:34 【问题描述】:

正如标题所说,我收到此错误:

无法执行查询 [选择 this_.Id 作为 Id5_0_,this_.Username 作为 Username5_0_,this_.PasswordHash 作为 Password3_5_0_,this_.Salt 作为 Salt5_0_,this_.Token 作为 Token5_0_,this_.TokenStamp 作为 TokenStamp5_0_,this_.Role 作为 Role5_0_ FROM 用户 this_]" 断点时出错。

我正在尝试使用数据库中的用户进行简单登录,其中用户输入用户名和密码哈希。我有一个用户数据,每列都有管理员进行调试。

这是我的代码:

SQL Server 数据库:

User表:

CREATE TABLE [dbo].[User] 
(
    [Id]           UNIQUEIDENTIFIER NOT NULL,
    [Username]     NVARCHAR (50)    NULL,
    [PasswordHash] CHAR (64)        NOT NULL,
    [Salt]         CHAR (64)        NOT NULL,
    [Role]         UNIQUEIDENTIFIER NOT NULL,
    [Token]        NVARCHAR (50)    NOT NULL,
    [TokenStamp]   DATETIME         NULL,
    CONSTRAINT [PK_User] PRIMARY KEY CLUSTERED ([Id] ASC),
    CONSTRAINT [FK_User_Role] FOREIGN KEY ([Role]) REFERENCES [dbo].[Role] ([Id])
);

Role表:

CREATE TABLE [dbo].[Role]  
(
    [Id]   UNIQUEIDENTIFIER NOT NULL,
    [Name] NVARCHAR (50)    NULL,
    CONSTRAINT [PK_Role] PRIMARY KEY CLUSTERED ([Id] ASC)
);

WebService.cs:

using System.Linq;
using System.Net;
using System.Web.Services;
using NHibernate;
using Models;

[WebService(Namespace = "http://LambdAlarm.com/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]

public class LambdAlarmWebService : WebService

    [WebMethod]
    public HttpStatusCode Login(string username, string passwordHash)
    
        var factory = SessionFactory.Instance;
        var session = factory.OpenSession();
        var result = session.QueryOver<User>().List<User>();
        var user = new User();
        var login = result.FirstOrDefault(u => u.Username == username);

        if (user.Username == login.Username)
        
            return HttpStatusCode.OK;
        

        return HttpStatusCode.NotFound;
    

User模特:

using System;

namespace Models

    public class User : EntityBase
    
        public virtual string Username  get; set; 
        public virtual string PasswordHash  get; set; 
        public virtual string Salt  get; set; 
        public virtual Role Role  get; set; 
        public virtual string Token  get; set; 
        public virtual DateTime TokenStamp  get; set; 
    

Role模特:

namespace Models

    public class Role : EntityBase
    
        public virtual string Name  get; set; 
    

EntityBase:(所有模型都继承一个Guid属性的类)

using System;

namespace Models

    public class EntityBase
    
        public virtual Guid Id  get; set; 
    

UserMap:(NHibernate 映射)

using FluentNHibernate.Mapping;
using Models;

namespace NHibernate.Mapping

    public class UserMap : ClassMap<User>
    
        public UserMap()
        
            Table("User");
            Id(x => x.Id).GeneratedBy.GuidComb();
            LazyLoad();
            References(x => x.Role).Column("Role");
            Map(x => x.Username).Column("Username");
            Map(x => x.PasswordHash).Column("PasswordHash").Not.Nullable();
            Map(x => x.Salt).Column("Salt").Not.Nullable();
            Map(x => x.Token).Column("Token").Not.Nullable();
            Map(x => x.TokenStamp).Column("TokenStamp");
        
    

RoleMap:

using FluentNHibernate.Mapping;
using Models;

namespace NHibernate.Mapping

    public class RoleMap : ClassMap<Role>
    
        public RoleMap()
        
            Table("Role");
            Id(x => x.Id).GeneratedBy.GuidComb();
            LazyLoad();
            Map(x => x.Name).Column("Name");
        
    

SessionFactory:

using FluentNHibernate.Cfg;
using FluentNHibernate.Cfg.Db;
using Models;
using NHibernate.Conventions;

namespace NHibernate

    public static class SessionFactory
    
        private static ISessionFactory _sessionFactory;

        public static ISessionFactory Instance
        
            get
            
                if (_sessionFactory == null)
                
                    _sessionFactory = CreateSessionFactory();
                

                return _sessionFactory;
            
        

        private static ISessionFactory CreateSessionFactory()
        
            return Fluently.Configure()
                        .Database(MsSqlConfiguration.MsSql2012
                            .ConnectionString(c => c.FromConnectionStringWithKey("DatabaseConnectionString")))
                        .Mappings(m =>
                        
                            m.FluentMappings.Conventions.AddFromAssemblyOf<CustomForeignKeyConvention>();
                            m.FluentMappings.AddFromAssemblyOf<EntityBase>();
                        )
                        .BuildSessionFactory();
        
    

Conventions:

using FluentNHibernate;
using FluentNHibernate.Conventions;

namespace NHibernate.Conventions

    public class CustomForeignKeyConvention : ForeignKeyConvention
    
        protected override string GetKeyName(Member property, System.Type type)
        
            if (property == null)
            
                return type.Name;
            

            return property.Name;
        
    

差不多就是这样。如果有人可以帮忙,将不胜感激...

【问题讨论】:

你看过所有的内部异常了吗?大多数情况下,这将包含对实际问题的有用解释。您引用的异常文本只是 NH​​ibernate 为真正的错误信息提供额外上下文的方式。 【参考方案1】:

user 是 sql 中的保留字。您可以重命名您的表或让 nhibernate 在表名周围使用 ``。我想如果你改变了

Table("User"); 

Table("`User`");

它会起作用的。

【讨论】:

我相信 using backticks 是正确的方法 - “NHibernate 在运行时用您选择的数据库方言的正确转义序列替换反引号”

以上是关于使用 NHibernate 的 Web 服务中的“无法执行查询错误”的主要内容,如果未能解决你的问题,请参考以下文章

使用 IIS 7 的 NHibernate 会话

在 Nhibernate 中加载与获取

提高 nHibernate 数据访问层的性能

NHibernate 中的映射表枚举

流畅的 nHibernate 数据库连接

是否可以直接在 NHibernate 中设置引用的外键?