【发布时间】:2012-03-05 15:02:09
【问题描述】:
在我们的数据库中保存各种字段之前,我需要进行一些修剪。我们将 xml 从另一个应用程序反序列化为 EF 实体,然后插入它们。 xml 中很少有超过 4000 个字符的字段,我们不使用 TEXT 数据类型,而是希望对它们进行修剪。
我的想法是检查 MyDbContext.SaveChanges() 内的 MetadataWorkspace 和 DbChangeTracker 以查找任何 nvarchar(4000) 实体属性并修剪任何超过 4000 的字符串值。但我不知道如何处理这个问题。我找不到任何相关文件。我看到了few related questions,但没有人详细说明或提供任何代码示例。
这是我目前所得到的:
public override int SaveChanges()
{
//TODO: trim strings longer than 4000 where type is nvarchar(max)
MetadataWorkspace metadataWorkspace =
((IObjectContextAdapter) this).ObjectContext.MetadataWorkspace;
ReadOnlyCollection<EdmType> edmTypes =
metadataWorkspace.GetItems<EdmType>(DataSpace.OSpace);
return base.SaveChanges();
}
解决方案
这是我基于@GertArnold 的回答的解决方案。
// get varchar(max) properties
var entityTypes = metadataWorkspace.GetItems<EntityType>(DataSpace.CSpace);
var properties = entityTypes.SelectMany(type => type.Properties)
.Where(property => property.TypeUsage.EdmType.Name == "String"
&& property.TypeUsage.Facets["MaxLength"].Value.ToString() == "Max"
// special case for XML columns
&& property.Name != "Xml")
.Select(
property =>
Type.GetType(property.DeclaringType.FullName)
.GetProperty(property.Name));
// trim varchar(max) properties > 4000
foreach (var entry in ChangeTracker.Entries())
{
var entity = entry.Entity;
var entryProperties =
properties.Where(prop => prop.DeclaringType == entity.GetType());
foreach (var entryProperty in entryProperties)
{
var value =
((string) entryProperty.GetValue(entity, null) ?? String.Empty);
if (value.Length > 4000)
{
entryProperty.SetValue(entity, value.Substring(0, 4000), null);
}
}
}
【问题讨论】:
标签: entity-framework-4 ef-code-first