3
我需要做一些修剪,然後保存我們的數據庫中的各個領域。我們將其他應用程序的xml反序列化爲EF實體,然後插入它們。在xml中有幾個字段超過4000個字符,而不是使用TEXT數據類型,我們希望修改它們。如何在運行時檢查EF模型元數據?
我的想法是檢查MetadataWorkspace
和DbChangeTracker
內MyDbContext.SaveChanges()
找到任何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);
}
}
}
這是醜陋的,但它的作品。謝謝! – jrummell 2012-03-06 15:23:53
同意,它看起來非常容易在元數據模型中發生變化。 – 2012-03-06 15:26:19