正如标题所说:我得到一个错误,上面写着:“System.InvalidOperationException:生成XML文档时出错.---> System.InvalidOperationException:不期望类型RoleProxy。使用XmlInclude或SoapInclude属性用于指定静态未知的类型。“
我试图将数据库中的用户列表作为XML返回给Web服务(密码不包括在内)。
以下是一些代码:
MS SQL Server数据库:
用户表:
CREATE TABLE [dbo].[Users] (
[Id] NVARCHAR (50) NOT NULL,
[Username] NVARCHAR (50) NULL,
[Password] NVARCHAR (50) NOT NULL,
[Role] NVARCHAR (50) NOT NULL,
CONSTRAINT [PK_Users] PRIMARY KEY CLUSTERED ([Id] ASC),
CONSTRAINT [FK_Users_Role] FOREIGN KEY ([Role]) REFERENCES [dbo].[Role] ([Id])
);
角色表:
CREATE TABLE [dbo].[Role] (
[Id] NVARCHAR (50) NOT NULL,
[Name] NVARCHAR (50) NULL,
CONSTRAINT [PK_Role] PRIMARY KEY CLUSTERED ([Id] ASC)
);
WebService.cs
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Web.Services;
using NHibernate;
using Models;
using NHibernate.Mapping;
[WebService(Namespace = "http://LambdAlarm.com/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
public class LambdAlarmWebService : WebService
{
[WebMethod]
public List<Users> GetUser()
{
var factory = SessionFactory.Instance;
var session = factory.OpenSession();
var result = session.QueryOver<Users>().List<Users>();
return result.ToList(); //Where I suspect the error occurs.
}
}
Users.cs(Model)
namespace Models
{
public class Users : EntityBase
{
public virtual string Username { get; set; }
public virtual string Password { get; set; }
public virtual Role Role { get; set; }
}
}
Role.cs:
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; }
}
}
用户映射:
using FluentNHibernate.Mapping;
using Models;
namespace NHibernate.Mapping
{
public class UserMap : ClassMap<Users>
{
public UserMap()
{
Table("Users");
Id(x => x.Id).GeneratedBy.GuidComb();
LazyLoad();
References(x => x.Role).Column("Role");
Map(x => x.Username).Column("Username");
Map(x => x.Password).Column("Password").Not.Nullable();
}
}
}
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");
}
}
}
会话工厂:
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();
}
}
}
公约:
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;
}
}
}
任何人都知道问题是什么?帮助将不胜感激!
答案 0 :(得分:0)
你没有告诉NHibernate你需要什么,所以它会延迟所有引用对象。然而,这将生成代理。防止SELECT N + 1的最简单的解决方案是急切加载角色。还要摆脱结果列表的冗余复制。
[WebMethod]
public List<Users> GetUser()
{
var factory = SessionFactory.Instance;
using (var session = factory.OpenSession())
{
return session.QueryOver<Users>().Fetch(u => u.Role).List();
}
}