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

发布于 2024-11-15 05:43:08 字数 1758 浏览 1 评论 0原文

它是如何开始的?

我想将业务对象集合中没有的两列添加到 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 类是部分类,我可以简单地通过部分类向它们添加属性,但我只想要这些网格而不是其他任何地方。

How it started?

I wanted to add two columns, that are not in business objec collection into radGridView. Specifically NewUrl anad NewIdOnFilehost. :)

So what i tried to do?

I put this into grid

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

Then i added them new columns

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

So what is problem?

radGridViewReuploadStatus.Rows does not exists.
I don't know why they did not added it to wpf radGridView, it is in its aspx version. I was able to get rows using getChildsOfType, but this is obviously not ideal way.

What i did next?

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

Finally the PROBLEM - what basic i don't understand

How do i make dlExtended from DownloadLink? (i know it is wrong name convention, it is just for example :) )
And how do i make list of dlExtended from collection of DownloadLink? There must be better way then using foreach!

Now i'm probably doing it wrong

So now i should do constructor and set EACH property of dlExneded according to one passed in passed DownloadLink?!

Well maybe it is doable by reflection LIKE this

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

Well this is stupid. So what i don't get about extending the class and adding new properties to it?

I know that EF4 classes are partial and i can add properties to them simply via partial class, but i want these only for the grid and not anywhere else.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

新人笑 2024-11-22 05:43:08

我的“浅层”对象复制器与您的非常相似,但空测试略有不同。它还有一个方便的扩展方法包装器 - 因此它需要位于静态类中。

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

My "Shallow" object copier is very similar to yours, but the null test is subtly different. It also has a handy extension method wrapper - so it will need to be in a static class.

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

However, I also have a deep copier, but this only works with serializable objects, so look into the code generation you use from the EDMX, I don't think it will work with the EF classes directly, but does with the POCO generated classes.

/// <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);
        }
    }
盛夏尉蓝 2024-11-22 05:43:08

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

将属性复制到一个地方。

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

If these are EF classes (not POCO from the T4 templates) then you may not want to inherit from them anyway - because you end up with the the EF baggage. That aside I think there are a number of potential solutions.

If its only used in one place, you can improve on the for loop with projection in Linq

var newthings = oldlinks.Select(old => new dlExtended{ NewUrl =old.NewUrl , NewIdOnFilehost =old.NewIdOnFilehost });

you can also write a constructor for dlExtended that takes a DownloadLink and then do

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

which puts the property copying in one place.

you can also build a generic extension method to copy properties with the same name between two objects and use that in a variety of ways.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文