扩展(继承)实体框架类(不使用部分)

时间:2011-06-13 16:37:18

标签: c# class inheritance entity-framework-4 extend

如何开始?

我想添加两个不在业务对象集合中的列到radGridView中。特别是NewUrl anad NewIdOnFilehost。 :)

那么我试图做什么?

我把它放到网格中

radGridViewReuploadStatus.ItemsSource = FileHostings.Filesonic.getdAllDeletedLinks();

然后我添加了新列

<telerik:GridViewColumn Header="New F.H.Id" UniqueName="NewFilehostId" Width="*"></telerik:GridViewColumn>
                <telerik:GridViewColumn Header="New URL" UniqueName="NewUrl" Width="*"></telerik:GridViewColumn>

那么问题是什么?

radGridViewReuploadStatus.Rows不存在。 我不知道为什么他们没有将它添加到wpf radGridView,它是在它的aspx版本中。我能够使用getChildsOfType获取行,但这显然不是理想的方式。

我接下来做了什么?

class dlExtended : DownloadLink {
        public string NewUrl { get; set; }
        public string NewIdOnFilehost { get; set; }
    }

最后问题 - 基本我不明白

如何从DownloadLink制作dlExtended? (我知道这是错误的名称约定,它只是例如:)) 如何从DownloadLink集合中创建dlExtended列表?必须有更好的方法然后使用foreach!

现在我可能做错了

所以现在我应该做构造函数并根据传递给DownloadLink的传递来设置dlExneded的EACH属性?!

好吧也许它可以通过反射来实现这个

public DownloadLinkExtended(DownloadLink origDl){
        PropertyInfo[] myObjectProperties = origDl.GetType().GetProperties(); //BindingFlags.Public | BindingFlags.NonPublic
        foreach (PropertyInfo pi in myObjectProperties)
        {
            if (pi.GetValue(origDl, null) != null)
            {
                pi.SetValue(this, pi.GetValue(origDl, null), null);
            }
        }
    }

这是愚蠢的。 那么我不会扩展课程并为其添加新属性?

我知道EF4类是部分的,我可以简单地通过部分类向它们添加属性,但我希望这些仅用于网格,而不是其他任何地方。

2 个答案:

答案 0 :(得分:0)

如果这些是EF类(不是来自T4模板的POCO),那么你可能不想继承它们 - 因为你最终得到了EF行李。除此之外,我认为有很多潜在的解决方案。

如果它只在一个地方使用,你可以在Linq

中使用投影改进for循环
var newthings = oldlinks.Select(old => new dlExtended{ NewUrl =old.NewUrl , NewIdOnFilehost =old.NewIdOnFilehost });

你也可以为dlExtended编写一个构造函数,它接受一个DownloadLink,然后执行

var newthings = oldlinks.Select(old => new dlExtended(old));

将属性复制到一个地方。

您还可以构建一个通用扩展方法,在两个对象之间复制具有相同名称的属性,并以多种方式使用它。

答案 1 :(得分:0)

我的“浅”对象复印机与你的非常相似,但是空测试略有不同。它还有一个方便的扩展方法包装器 - 所以它需要在一个静态类中。

    /// <summary>
    /// Copy an object to destination object, only matching fields will be copied
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="sourceObject">An object with matching fields of the destination object</param>
    /// <param name="destObject">Destination object, must already be created</param>
    public static void ShallowCopyTo<T>(this object sourceObject, ref T destObject)
    {
        Copy<T>(sourceObject,ref destObject);
    }
    /// <summary>
    /// Copy an object to destination object, only matching fields will be copied
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="sourceObject">An object with matching fields of the destination object</param>
    /// <param name="destObject">Destination object, must already be created</param>
    public static void Copy<T>(object sourceObject, ref T destObject)
    {
        //  If either the source, or destination is null, return
        if (sourceObject == null || destObject == null)
            return;

        //  Get the type of each object
        Type sourceType = sourceObject.GetType();
        Type targetType = destObject.GetType();

        //  Loop through the source properties
        foreach (PropertyInfo p in sourceType.GetProperties())
        {
            //  Get the matching property in the destination object
            PropertyInfo targetObj = targetType.GetProperty(p.Name);
            //  If there is none, skip
            if (targetObj == null)
                continue;

            //  Set the value in the destination
            targetObj.SetValue(destObject, p.GetValue(sourceObject, null), null);
        }
    }

但是,我也有一个深度复印机,但这只适用于可序列化的对象,所以看看你在EDMX中使用的代码生成,我不认为它可以直接使用EF类,但是POCO生成了类。

/// <summary>
/// Reference Article http://www.codeproject.com/KB/tips/SerializedObjectCloner.aspx
/// 
/// Provides a method for performing a deep copy of an object.
/// Binary Serialization is used to perform the copy.
/// </summary>

public static class ObjectCopier
{
    /// <summary>
    /// Perform a deep Copy of the object.
    /// </summary>
    /// <typeparam name="T">The type of object being copied.</typeparam>
    /// <param name="source">The object instance to copy.</param>
    /// <returns>The copied object.</returns>
    public static T Clone<T>(this T source)
    {
        if (!typeof(T).IsSerializable)
        {
            throw new ArgumentException("The type must be serializable.", "source");
        }

        // Don't serialize a null object, simply return the default for that object
        if (Object.ReferenceEquals(source, null))
        {
            return default(T);
        }

        IFormatter formatter = new BinaryFormatter();
        Stream stream = new MemoryStream();
        using (stream)
        {
            formatter.Serialize(stream, source);
            stream.Seek(0, SeekOrigin.Begin);
            return (T)formatter.Deserialize(stream);
        }
    }