jru*_*ell 3 entity-framework-4 ef-code-first
在保存数据库中的各个字段之前,我需要进行一些修剪.我们将xml从另一个应用程序反序列化为EF实体,然后插入它们.xml中有少量字段超过4000个字符,而不是使用TEXT数据类型,我们希望修改它们.
我的想法是检查MetadataWorkspace和DbChangeTracker内部MyDbContext.SaveChanges()找到任何nvarchar(4000)实体属性并修剪任何超过4000的字符串值.但我不知道如何处理这个.我找不到任何相关文件.我看到了一些相关的问题,但没有任何细节或提供任何代码示例.
这是我到目前为止所得到的:
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();
}
Run Code Online (Sandbox Code Playgroud)
解
这是基于@ 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);
}
}
}
Run Code Online (Sandbox Code Playgroud)
您可以通过以下代码找到属性:
var varchars = context.MetadataWorkspace.GetItemCollection(DataSpace.CSpace)
.Where(gi => gi.BuiltInTypeKind == BuiltInTypeKind.EntityType)
.Cast<EntityType>()
.SelectMany(entityType => entityType.Properties
.Where(edmProperty => edmProperty.TypeUsage.EdmType.Name == "String")
.Where(edmProperty => (int)(edmProperty.TypeUsage.Facets["MaxLength"]
.Value) >= 4000))
.ToList();
Run Code Online (Sandbox Code Playgroud)
诀窍是从模型中提取实体类型BuiltInTypeKind.EntityType并将其转换EntityType为访问权限Properties.EdmProperty有一个属性DeclaringType,显示它们属于哪个实体.
| 归档时间: |
|
| 查看次数: |
3539 次 |
| 最近记录: |