实体框架代码首先忽略了复杂类型 [英] Complex Type Ignored by Entity Framework Code First

查看:98
本文介绍了实体框架代码首先忽略了复杂类型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述



实体框架代码首先和原始类型的集合



我正在尝试创建一个包装器类型 EfObservableCollection< T> 围绕 ObservableCollection< T> 有一个额外的辅助属性来简化持久性(当然这个解决方案有权衡,但是,对我的域来说似乎是可行的)。



但是,类型 EfObservableCollection< T> 的属性似乎被忽略由EF。在数据库中没有创建适当的列。猜测实现 IEnumerable< T> 可能会触发EF忽略该类型,我评论了该实现,而不改变行为。



我在这里缺少什么?



实体类

  public class A 
{
[DataMember]
public long Id {get;组; }

[DataMember]
public string Text {get;组;

//标签不保留
[DataMember]
public EfObservableCollection< string>标签{get;组;
}

包装类

  [ComplexType] 
public class EfObservableCollection< T> :IEnumerable< T>
{
const string VALUE_SEPARATOR =\x8; //退格字符不太可能实际上是由用户输入的。假设ASCII或UTF-8。
readonly string [] VALUE_SEPARATORS = new string [] {VALUE_SEPARATOR};

[NotMapped]
protected ObservableCollection< T>收藏{get;私人集合}

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必须实现IConvertable,否则运行时异常。
}
}
}

public void Add(T item)
{
Collection.Add(item);
}

IEnumerator< T> GetEnumerator()
{
return Collection.GetEnumerator();
}

System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
返回GetEnumerator();
}
}


解决方案

事实证明,实体框架不喜欢通用类 EfObservableCollection< T>



数据按预期持久化:

  [ComplexType] 
public class EfObservableCollectionString:EfObservableCollection< string> ;
{
}


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();
    }
}   

解决方案

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>
{
}

这篇关于实体框架代码首先忽略了复杂类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆