开发者

Extending (inherit) entity framwork class (not using partial)

开发者 https://www.devze.com 2023-03-12 08:12 出处:网络
How it started? I wanted to add two columns, that are not in business objec collection into radGridView. Specifically NewUrl anad NewIdOnFilehost. :)

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().GetPro开发者_StackOverflow社区perties(); //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.


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


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.

0

精彩评论

暂无评论...
验证码 换一张
取 消