And*_*sti 6 .net c# sql-server nhibernate web-services
正如标题所说,Iam收到一条错误消息:"在创建SessionFactory时使用了无效或不完整的配置.检查PotentialReasons集合,并查看InnerException以获取更多详细信息."
我将从代码开始.
数据库:
用户表:
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])
);
Run Code Online (Sandbox Code Playgroud)
角色表:
CREATE TABLE [dbo].[Role] (
[Id] UNIQUEIDENTIFIER NOT NULL,
[Name] NVARCHAR (50) NULL,
CONSTRAINT [PK_Role] PRIMARY KEY CLUSTERED ([Id] ASC)
);
Run Code Online (Sandbox Code Playgroud)
用户类:
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 Guid Role { get; set; }
public virtual string Token { get; set; }
public virtual DateTime TokenStamp { get; set; }
}
}
Run Code Online (Sandbox Code Playgroud)
角色类:
namespace Models
{
public class Role : EntityBase
{
public virtual string Name { get; set; }
}
}
Run Code Online (Sandbox Code Playgroud)
EntityBase:
using System;
namespace Models
{
public class EntityBase
{
public virtual Guid Id { get; set; }
}
}
Run Code Online (Sandbox Code Playgroud)
用户地图:
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");
}
}
}
Run Code Online (Sandbox Code Playgroud)
角色地图:
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");
}
}
}
Run Code Online (Sandbox Code Playgroud)
CustomForeignKeyConvention:
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;
}
}
}
Run Code Online (Sandbox Code Playgroud)
会议工厂:
using FluentNHibernate.Cfg;
using FluentNHibernate.Cfg.Db;
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<Models.EntityBase>();
})
.BuildSessionFactory();
}
}
}
Run Code Online (Sandbox Code Playgroud)
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 password)
{
var factory = SessionFactory.Instance;
var session = factory.OpenSession();
var result = session.QueryOver<User>().List<User>();
var login = result.Where(u => u.Username == username).Where(p => p.PasswordHash == password);
return HttpStatusCode.NotFound;
}
}
Run Code Online (Sandbox Code Playgroud)
所以是的...这不是一件容易的事.我认为数据库中的外键关系与User和Role表有关.角色列应引用角色表中的Id.
请帮忙!
问题在于它References()是指引用另一个实体,而不是类型.如果要使用类型,则应使用Map(x => x.Role)而不是References(x => x.Role)
改变User这样的:
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; } //CHANGED HERE
public virtual string Token { get; set; }
public virtual DateTime TokenStamp { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
你UserMap的:
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");
}
Run Code Online (Sandbox Code Playgroud)
此外,在使用Fluent NHibernate进行映射时,没有理由指定列名.默认情况下,它只会使用您的属性的名称,所以类似于Map(x => x.Name).Column("Name").Not.Nullable(),Map(x => x.Name).Not.Nullable()
其他一些建议:
为映射创建基类以使其更容易:
public abstract class ClassMapBase<T> : ClassMap<T> where T: EntityBase
{
protected ClassMapBase()
{
Id(x => x.Id).Not.Nullable().GeneratedBy.GuidComb();
LazyLoad();
}
}
Run Code Online (Sandbox Code Playgroud)
另外,我很惊讶,NHibernate的不是抱怨你的Id上EntityBase有一个公共的制定者.它应该设置为受保护或私有.除非您希望它与实体名称不同,否则也无需指定表名
小智 5
尽管有一个正确的答案,但我只会提供另一个可能对其他人有用的解决方案。当您的应用程序无法访问数据库时会导致此错误。所以:
services.exe并查看您的 SQL Server 是否正在运行| 归档时间: |
|
| 查看次数: |
18102 次 |
| 最近记录: |