![](/img/trans.png)
[英]WPF - NotMapped annotation in EF6 not storing / saving property value(s)
[英]EF SqlQuery tries to map object property, even though it's attributed [NotMapped]
我有一个存储过程,我使用context.Database.SqlQuery<MyObject>("MyProc")
MyObject
具有只读属性:
[NotMapped]
public bool IsSomething { get { return this.otherproperty == "something"; } }
所以我得到错误:
System.IndexOutOfRangeException:IsSomething at System.Data.ProviderBase.FieldNameLookup.GetOrdinal etc
这是因为MyProc在结果列中没有IsSomething
(我100%肯定这可能是原因)。
它不应该忽略它,因为它是[NotMapped]
? 我是否需要为SqlQuery
设置其他内容?
为了让事情变得更加奇怪,我只在生产中看到它,从Stackify的日志中看,并且页面似乎正确加载而浏览器没有任何错误。
根据文件
Database.SqlQuery<TElement> Method (String, Object[])
创建将返回给定泛型类型的元素的原始SQL查询。 类型可以是具有与查询返回的列的名称匹配的属性的任何类型,也可以是简单的基本类型。 该类型不必是实体类型。 即使返回的对象类型是实体类型,上下文也不会跟踪此查询的结果.....
强调我的
它正在查询从查询中返回的IsSomething
如错误消息中的System.Data.ProviderBase.FieldNameLookup.GetOrdinal
所示。
因为该列不存在,您将获得IndexOutOfRangeException
。
它不应该忽略它,因为它是
[NotMapped]
?
不会。它会忽略对象上存在的任何属性,包括[NotMapped]
。 请参阅上面引用的引用
我是否需要为SqlQuery设置其他内容?
我建议创建另一个对象,只有属性匹配/映射到过程的预期结果,并使用它作为SqlQuery
调用的泛型参数。
为了让事情变得更加奇怪,我只在生产中看到它,从Stackify的日志开始,页面似乎正确加载而没有任何错误
我不熟悉Stackify日志,但根据我对EF6的了解,我会推测并说这是误报日志。
在这方面,文件并不十分清楚。 首先,实体和非实体SqlQuery
结果类型由不同的代码分支处理。 虽然两个转换都使用CLR属性名作为列名(即不考虑实体类型的列名映射),但NotMapped
类型的忽略( NotMapped
)属性确实从结果中排除 。
此外,有问题的IndexOutOfRangeException
被EF代码捕获并转换为另一个异常( EntityCommandExecutionException
),可以从相关方法GetMemberOrdinalFromReader
的源代码中看到:
// <summary>
// Given a store datareader and a member of an edmType, find the column ordinal
// in the datareader with the name of the member.
// </summary>
private static int GetMemberOrdinalFromReader(
DbDataReader storeDataReader, EdmMember member, EdmType currentType,
Dictionary<string, FunctionImportReturnTypeStructuralTypeColumnRenameMapping> renameList)
{
int result;
var memberName = GetRenameForMember(member, currentType, renameList);
if (!TryGetColumnOrdinalFromReader(storeDataReader, memberName, out result))
{
throw new EntityCommandExecutionException(
Strings.ADP_InvalidDataReaderMissingColumnForType(
currentType.FullName, member.Name));
}
return result;
}
和TryGetColumnOrdinalFromReader
:
// <summary>
// Given a store datareader and a column name, try to find the column ordinal
// in the datareader with the name of the column.
// </summary>
// <returns> true if found, false otherwise. </returns>
private static bool TryGetColumnOrdinalFromReader(DbDataReader storeDataReader, string columnName, out int ordinal)
{
if (0 == storeDataReader.FieldCount)
{
// If there are no fields, there can't be a match (this check avoids
// an InvalidOperationException on the call to GetOrdinal)
ordinal = default(int);
return false;
}
// Wrap ordinal lookup for the member so that we can throw a nice exception.
try
{
ordinal = storeDataReader.GetOrdinal(columnName);
return true;
}
catch (IndexOutOfRangeException)
{
// No column matching the column name found
ordinal = default(int);
return false;
}
}
基于以上和缺乏repro与真正的异常,我会说你可以安全地忽略该日志。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.