J'utilise un Entity-Framework ObjectContext ADO.NET pour accéder à mon magasin de données. Je veux que les valeurs if soient définies avec des chaînes vides, elles devraient automatiquement devenir nulles.Existe-t-il une option permettant à Entity Framework de rétablir les chaînes vides à null?
Répondre
j'ai trouvé une meilleure façon de En fait, il est construit dans le système, et utilise les métadonnées ordinales internes des entités qui sont chargées (je n'ai pas testé la différence de performance, mais cela devrait être bien plus rapide que la réflexion):
private const string StringType = "String";
private const EntityState SavingState = EntityState.Added | EntityState.Modified;
public override int SaveChanges()
{
//when using on ObjectContext replace 'objectContext' with 'this',
//and override SaveChanges(SaveOptions options) instead:
var objectContext = ((IObjectContextAdapter)this).ObjectContext;
var savingEntries = objectContext.ObjectStateManager
.GetObjectStateEntries(SavingState);
foreach (var entry in savingEntries)
{
var curValues = entry.CurrentValues;
var fieldMetadata = curValues.DataRecordInfo.FieldMetadata;
var stringFields = fieldMetadata
.Where(f => f.FieldType.TypeUsage.EdmType.Name == StringType);
foreach (var stringField in stringFields)
{
var ordinal = stringField.Ordinal;
var curValue = curValues[ordinal] as string;
if (curValue != null && curValue.All(char.IsWhiteSpace))
curValues.SetValue(ordinal, null);
}
}
return base.SaveChanges(); //SaveChanges(options) on ObjectContext
}
Pas que je sache.
Vous pourriez peut-être écrire une classe qui a hérité de ObjectContext
et passer outre SaveChanges()
de le faire et utiliser à la place de ObjectContext
dans votre x.objectlayer.cs/x.designer.cs
oups, alors que j'écris ceci, vous l'avez posté ...lol merci, j'ai voté – Shimmy
Si vous utilisez Entity Framework 4, vous pouvez utiliser des modèles T4 pour accompagner ça. Placez-le simplement dans le getter de chaque propriété de chaîne dans votre fichier de modèle .tt, et il remplacera les chaînes vides par des chaînes nulles et automatiquement ajustées. Pas besoin d'utiliser la réflexion.
<#+ if (primitiveProperty.TypeUsage.ToString().Split('.').Last() == "String") { #>
if (value == "") value = null;
else value = value.Trim();
<#+ } #>
Nous utilisons Reverse POCO Generator et j'ai en fait besoin de l'inverse (convertir les chaînes null à vide). Savez-vous si votre suggestion est valable pour ce scénario? – Naomi
Je viens d'adapter le code ci-dessus à la nouvelle version d'Entity Framework 4.1 (DbContext).
public override int SaveChanges()
{
var objContext = ((IObjectContextAdapter)this).ObjectContext;
var entries = objContext.ObjectStateManager.GetObjectStateEntries(EntityState.Added | EntityState.Modified).Select(
entry => entry.Entity);
foreach (var entity in entries)
{
string str = typeof(string).Name;
var properties = from p in entity.GetType().GetProperties()
where p.PropertyType.Name == str
select p;
foreach (var item in properties)
{
string value = (string)item.GetValue(entity, null);
if (value != null && value.Trim().Length == 0)
{
item.SetValue(entity, null, null);
}
}
}
return base.SaveChanges();
Plutôt que de compliquer les choses en redéfinissant la ObjectContext J'utilise des méthodes d'extension de chaîne pour convertir les valeurs pour le stockage de base de données
public static class StringExtensions
{
public static string EmptyStringToNull(this string s)
{
return string.IsNullOrWhiteSpace(s) ? null : s;
}
public static object EmptyStringToDBNull(this string s)
{
if (string.IsNullOrWhiteSpace(s))
return DBNull.Value;
else
return s;
}
}
Etes-vous sûr que cela va marcher sur les requêtes DB? Je crois que ce ne sera pas le cas. – Shimmy
Juste pour être complet, voici la réponse acceptée par écrit en tant que classe partielle au lieu de héritée . Notez que cette version coupe également les chaînes.
using System.Data;
using System.Data.Objects;
using System.Linq;
public partial class MyObjectContext {
private const string StringType = "String";
private const EntityState SavingState = EntityState.Added | EntityState.Modified;
public override int SaveChanges(SaveOptions options) {
var savingEntries = this.ObjectStateManager.GetObjectStateEntries(SavingState);
foreach (var entry in savingEntries) {
var curValues = entry.CurrentValues;
var fieldMetadata = curValues.DataRecordInfo.FieldMetadata;
var stringFields = fieldMetadata.Where(f => f.FieldType.TypeUsage
.EdmType.Name == StringType);
foreach (var stringField in stringFields) {
var ordinal = stringField.Ordinal;
var curValue = curValues[ordinal] as string;
if (curValue != null && curValue.All(char.IsWhiteSpace)) {
curValues.SetValue(ordinal, null);
}
else if (curValue != null && curValue != curValue.Trim()) {
curValues.SetValue(ordinal, curValue.Trim());
}
}
}
return base.SaveChanges(options);
}
}
J'ai aussi montré la nécessaire usings
parce que je trouve frustrant quand je Copy'n'Paste code et l'IDE vomit des erreurs sur le type ou espace de noms introuvable.
J'ai utilisé Shimmy's solution et j'étais heureux jusqu'à ce que je découvre que les chaînes de mes types complexes étaient manquées. En d'autres termes, j'avais besoin d'un moyen d'annuler les chaînes d'espaces vides valables dans non seulement mon objet/enregistrement principal, mais toutes ses propriétés d'objet non-primitives, et leurs et leurs ...
adaptation récursive. Je ne peux pas parler de son élégance ou de la qualité de sa production parce qu'elle n'a pas été très vivante depuis longtemps, mais elle semble fonctionner pour moi jusqu'à présent et peut au moins servir de point de départ pour quelqu'un d'autre.
using System.Data.Entity;
using System.Data.Entity.Core.Metadata.Edm;
using System.Data.Entity.Core.Objects;
using System.Data.Entity.Infrastructure;
using System.Linq;
public class MyDataContext : DbContext
{
public override int SaveChanges()
{
ObjectStateEntry[] savingObjectStateEntries = ((IObjectContextAdapter)this)
.ObjectContext.ObjectStateManager
.GetObjectStateEntries(EntityState.Added | EntityState.Modified).ToArray();
foreach (ObjectStateEntry savingObjectStateEntry in savingObjectStateEntries)
SetEmptyStringsToNull(savingObjectStateEntry.CurrentValues);
return base.SaveChanges();
}
private static void SetEmptyStringsToNull(CurrentValueRecord currentValueRecord)
{
if (currentValueRecord != null)
for (int i = 0; i < currentValueRecord.FieldCount; i++)
if (currentValueRecord[i] is CurrentValueRecord)
SetEmptyStringsToNull(currentValueRecord[i] as CurrentValueRecord);
else if ((currentValueRecord[i] is string)
&& (currentValueRecord.DataRecordInfo.FieldMetadata[i].FieldType as EdmProperty).Nullable
&& string.IsNullOrWhiteSpace(currentValueRecord[i] as string))
currentValueRecord.SetValue(i, null);
}
}
Voici une solution pour Entity Framework Core (testé en V2). J'ai dû me frayer un chemin à travers l'API en raison d'une documentation limitée, donc il pourrait y avoir d'autres façons d'accomplir la même chose. Notez que les objets d'origine sont modifiés à l'aide de cette méthode.
public override int SaveChanges()
{
ConvertWhitespaceToNulls();
return base.SaveChanges();
}
private void ConvertWhitespaceToNulls()
{
var entityEntries = this.ChangeTracker
.Entries()
.Where(x => x.State == EntityState.Modified || x.State == EntityState.Added && x.Entity != null);
foreach (var e in entityEntries)
foreach (var currentValue in e.CurrentValues.Properties.Where(p => p.ClrType == typeof(string) && p.IsNullable))
if (string.IsNullOrWhiteSpace((string) currentValue.FieldInfo.GetValue(e.Entity)))
currentValue.FieldInfo.SetValue(e.Entity, null);
}
- 1. cartographie des chaînes vides à NULL dans NHibernate
- 2. Comment accéder à Entity Framework
- 3. Entités à DTO - Entity framework
- 4. Entity Framework, WCF et mises à jour
- 5. Entity Framework Les associations
- 6. Les chaînes de connexion Entity Framework peuvent-elles réutiliser une chaîne de connexion existante?
- 7. C#: XmlTextWriter.WriteElementString échoue sur les chaînes vides?
- 8. C# Listbox lié à l'entité "Entity Framework"
- 9. Ajout d'une propriété à une Entity Framework Entity à partir d'une autre table
- 10. Entity Framework Beaucoup-à-plusieurs + nombre
- 11. ADO.NET Entity Framework - LINQ à plusieurs dbms
- 12. Entity Framework Beaucoup à beaucoup CRUD
- 13. Entity Framework and Sorting
- 14. Entity Framework Mapping Question
- 15. Entity Framework - Détaché Mettre à jour le numéro
- 16. Impossible d'enregistrer les types Entity Framework Inherited
- 17. Comment définir un champ à DBNull dans Entity Framework
- 18. Comment rétablir une connexion au serveur à l'aide de Flex?
- 19. Vues et Entity Framework
- 20. Pensez-vous qu'il est avantageux de passer à Entity Framework?
- 21. Instruction de mise à jour avec Entity Framework
- 22. Entity Framework IQueryable
- 23. Null vs collections vides dans Hibernate
- 24. Créer une condition Remplace dans Entity Framework
- 25. Entity Framework - L'héritage
- 26. entity-framework une table sans clé unique
- 27. convertir une requête SQL pour Entity Framework
- 28. Audit dans Entity Framework
- 29. Entity Framework and Encapsulation
- 30. Entity Framework + POCO
D'un autre forum, je suis arrivé cette réponse http://msdn.microsoft.com/en-us/library/vstudio/ms366709(v=vs.100).aspx (propriété ConvertEmptyStringToNull) – Naomi
Salut Naomi, je Je suis content que vous l'ayez trouvé, pourquoi ne pas répondre vous-même? – Shimmy