【发布时间】:2018-04-17 20:54:48
【问题描述】:
C#/.Net 4.6.1/Visual Studio 2017
我遇到了 MS SQL 查询问题。该查询将跨两个数据库(在同一台服务器上)的多个表连接起来。结果进入“对象”列表。我得到的例外是:
从具体化的“System.Int32”中指定的演员表 'System.Int64' 类型的类型无效。
我已经看到有关此错误和类似错误的其他 SO 问题,但我在这里没有看到问题。 personId 很长。所有各种...Id 字段在数据库中为bigint,在模型中为long。
查询是:
try {
var personId = GetPersonId(netid);
var personIdParam = new SqlParameter {
Value = personId,
DbType = DbType.Int64,
ParameterName = "PERSONID"
};
using (var pdb = new PersonnelContext()) {
var foo = pdb.Database.SqlQuery<PersonToSpaceInfo>(@"
SELECT
'Member',
sGroup.GroupId,
sGroup.PersonnelGroupId,
sGroup.Name,
Space.SpaceId,
Space.RoomId,
SiteSpaceUse.TypeDescription
FROM
Personnel.Personnel.Memberships AS Memberships
INNER JOIN Space.dbo.Person AS Person
ON Memberships.PersonId = Person.PersonnelPersonId
AND Person.PersonnelPersonId = @PERSONID
INNER JOIN Space.dbo.[Group] AS sGroup
ON Memberships.GroupId = sGroup.PersonnelGroupId
INNER JOIN Space.dbo.GroupList AS GroupList
ON sGroup.GroupId = GroupList.GroupId
INNER JOIN Space.dbo.Space AS Space
ON GroupList.SpaceId = Space.SpaceId
AND Space.IsActive = 1
INNER JOIN Space.dbo.SiteSpaceUse AS SiteSpaceUse
ON Space.SpaceId = SiteSpaceUse.SpaceId
WHERE GETDATE() BETWEEN Memberships.StartDate
AND ISNULL(Memberships.EndDate, GETDATE())
",
personIdParam).ToList();
}
} catch (Exception e) {
throw new Exception("get group list failed: " + e.Message);
}
结果对象是:
public class PersonToSpaceInfo {
public string PersonType { get; set; }
public long GroupId { get; set; }
public long PersonnelGroupId { get; set; }
public string GroupName { get; set; }
public long SpaceId { get; set; }
public string RoomId { get; set; }
public string TypeDescription { get; set; }
}
堆栈跟踪:
at System.Data.Entity.Core.Common.Internal.Materialization.Shaper.ErrorHandlingValueReader`1.GetValue(DbDataReader reader, Int32 ordinal)
at lambda_method(Closure , Shaper )
at System.Data.Entity.Core.Common.Internal.Materialization.Coordinator`1.ReadNextElement(Shaper shaper)
at System.Data.Entity.Core.Common.Internal.Materialization.Shaper`1.SimpleEnumerator.MoveNext()
at System.Data.Entity.Internal.LazyEnumerator`1.MoveNext()
at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
at MyProject.Controllers.HomeController.GetUserActiveGroups(String user) in C:\Users\me\Projects\MyProject\MyProject\Controllers\HomeController.cs:line 560
编辑
堆栈跟踪中的第 560 行是上面的 var foo = pdb.Database... 行。 GetPersonId() 返回long。
模型是使用代码优先界面创建的。以下是@mjwills 要求的模型sn-ps
GroupList.GroupId / GroupList.SpaceId
public partial class GroupList {
public long GroupId { get; set; }
public long SpaceId { get; set; }
...
}
Memberships.GroupId / Memberships.PersonId
public partial class Membership {
public long PersonId { get; set; }
public long GroupId { get; set; }
...
}
Person.PersonnelPersonId
public partial class Person {
public long PersonId { get; set; }
public long PersonnelPersonId { get; set; }
...
}
SiteSpaceUse.SpaceId
public partial class SiteSpaceUse {
public long SpaceId { get; set; }
...
}
Space.SpaceId
public partial class Space
public long SpaceId { get; set; }
public long BuildingId { get; set; }
...
}
sGroup.GroupId / sGroup.PersonnelGroupId
public partial class Group {
public long GroupId { get; set; }
public long PersonnelGroupId { get; set; }
...
}
编辑 2
刚刚尝试用有效的三位数替换查询中的SqlParameter,但我仍然收到错误消息。该查询在 SQL Server Management Studio 中工作。我将删除模型和连接字符串信息并重新创建以查看会发生什么。
发生的事情是注意到变化......
【问题讨论】:
-
这发生在哪一行?
var personId = GetPersonId(netid);实际返回什么(int32 或 int64)? -
stacktrace 中的第 560 行是上面的
var foo = pdb.Database.SqlQuery<PersonToSpaceInfo>(...)行。GetPersonId返回long。 -
你能通过这样声明来向我们保证 personId 是 long 吗?
-
是的。将
var personId = GetPersonId(netid);更改为long personId ; personId = GetPersonId(netid);既编译又运行,并且在同一个地方抛出相同的异常。 -
@ClayVerValen:我没有看到与我的模型关联的 XML 文件。如果这有所作为,这些都是代码优先的。如果您感兴趣的文件具有特定名称或应该位于特定位置,请告诉我。我用winGrep在整个项目中搜索了
<EntityType...,找不到匹配项。
标签: c# .net sql-server