问题
Building on Ladislav's answer to
Entity Framework Code First and Collections of Primitive Types
I'm attempting to create a wrapper type EfObservableCollection<T>
around an ObservableCollection<T>
that has an additional helper property to simplify persistence (certainly this solution has trade-offs, but it's seems workable for my domain).
However, properties of type EfObservableCollection<T>
seem to be ignored by EF. No appropriate columns are created in the database. Guessing that implementing IEnumerable<T>
might trigger EF to ignore that type, I commented out that implementation with no change in behavior.
What am I missing here?
Entity Class
public class A
{
[DataMember]
public long Id { get; set; }
[DataMember]
public string Text { get; set; }
// Tags is not persisted
[DataMember]
public EfObservableCollection<string> Tags { get; set; }
}
Wrapper Class
[ComplexType]
public class EfObservableCollection<T> : IEnumerable<T>
{
const string VALUE_SEPARATOR = "\x8"; // Backspace character. Unlikely to be actually entered by a user. Assumes ASCII or UTF-8.
readonly string[] VALUE_SEPARATORS = new string[] { VALUE_SEPARATOR };
[NotMapped]
protected ObservableCollection<T> Collection { get; private set; }
public EfObservableCollection()
{
Collection = new ObservableCollection<T>();
}
[DataMember]
public string PersistHelper
{
get
{
string serializedValue = string.Join(VALUE_SEPARATOR, Collection.ToArray());
return serializedValue;
}
set
{
Collection.Clear();
string[] serializedValues = value.Split(VALUE_SEPARATORS, StringSplitOptions.None);
foreach (string serializedValue in serializedValues)
{
Collection.Add((T)Convert.ChangeType(serializedValue, typeof(T))); // T must implement IConvertable, else a runtime exception.
}
}
}
public void Add(T item)
{
Collection.Add(item);
}
IEnumerator<T> GetEnumerator()
{
return Collection.GetEnumerator();
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
回答1:
It turns out that Entity Framework does not like the generic class EfObservableCollection<T>
.
If I derive a non-generic class from that class, data is persisted as expected:
[ComplexType]
public class EfObservableCollectionString : EfObservableCollection<string>
{
}
回答2:
Joining backspace with list of strings causes cleaning last character in each string item. I think serialization to json using System.Web.Script.Serialization.JavaScriptSerializer is better.
来源:https://stackoverflow.com/questions/8349682/complex-type-ignored-by-entity-framework-code-first