【问题标题】:Extending (inherit) entity framwork class (not using partial)扩展(继承)实体框架类(不使用部分)
【发布时间】:2011-09-14 01:47:04
【问题描述】:

它是如何开始的?

我想将不在业务对象集合中的两列添加到 radGridView 中。特别是 NewUrl 和 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 的每个属性?!

也许它可以通过像这样的反射来实现

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 类是部分的,我可以简单地通过部分类向它们添加属性,但我只希望这些用于网格而不是其他任何地方。

【问题讨论】:

  • 一种可能的解决方案的制定:如何继承类,使带有父类的参数实例的构造函数设置所有继承的属性?

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


【解决方案1】:

我的“Shallow”对象复制器与您的非常相似,但 null 测试略有不同。它还有一个方便的扩展方法包装器——所以它需要在一个静态类中。

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

【讨论】:

    【解决方案2】:

    如果这些是 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));
    

    将属性复制放在一个地方。

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

    【讨论】:

    • 感谢您的回答。你的拳头方法会很好,但我想在不止一个地方使用这个新课程。使用您的第二种方法,我仍然需要指定每个属性,例如 this.property1=orig.property1; this.property2=orig.property2; this.property3=orig.property3;对吗?这正是我不想要的。 “在两个对象之间复制具有相同名称的属性的扩展方法”实际上是我遇到的问题,因为我尝试使用不处理其他 EF 类的属性。
    • 无论如何,在快速谷歌之后,我认为你提到的 POCO,更具体地说是 visualstudiogallery.msdn.microsoft.com/…,并将其用作 MVVM 中的 ModelView 之类的东西,这可能是我正在寻找的解决方案,但是很好 - 我听说过 poco第一次来这里,所以需要时间研究:/我仍然想知道如何正确地反思。
    • 我认为最终将 EF 类传递到视图中的情况很少见。它可以工作,所有示例都可以,但实际上几乎所有现实世界的场景都需要一个 POCO Viewmodel - 一个代表视图所需数据的类。当数据库更改时保持这些同步是一个问题,实例化大量数字的性能是另一个问题。重新复制,我会用我的对象复制代码发布另一个答案,以防万一。
    • 我真的很惊讶你真的了解什么是问题以及我要解决什么问题。这不是实际的现实世界应用程序,它更多地用于学习目的。您是否知道任何关于保持视图模型与 dbb 同步的最佳实践/自动化的指南?
    • 我可能不知道你在做什么 :-) 但我确实知道我做了什么,以及我在学习过程中得到的建议。我还使用 Telerik 控件(主要是 MVC),并且知道如果涉及任何 JSON 序列化,原始 EF 类会变得“有趣”。将帖子绑定到 EF 模型(至少在 MVC 中)也是危险的,因为默认情况下会绑定任何发布的与属性匹配的数据。无论如何,同步视图模型 - 如果您发现任何比我发布的更好的内容,请添加:-)
    猜你喜欢
    • 2011-05-06
    • 1970-01-01
    • 2011-06-25
    • 2013-12-19
    • 2011-05-19
    • 2010-10-07
    • 1970-01-01
    相关资源
    最近更新 更多