1

プロジェクトでは、LINQ to SQL と WCF を使用しています。

次の単一テーブルの継承があります。

単一テーブルの継承

(基本型) オブジェクトのGetMediaForItemリストを返すWCF メソッド () を呼び出すと、例外が発生します。ItemMediaA first chance exception of type 'System.Runtime.Serialization.SerializationException' occurred in System.Runtime.Serialization.dll

しかし、(派生型の 1 つ) のGetYouTubeVideosForItemリストを返す WCF メソッド ( )を呼び出すと、正常に動作します。YouTubeVideo

[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
public class MediaService : IMediaService
{
    ...

    // this throws a System.Runtime.Serialization.SerializationException
    public List<ItemMedia> GetMediaForItem(int itemId)
    {
        using (var context = _db.CreateContext())
        {
            context.DeferredLoadingEnabled = false;

            return (from i in context.ItemMedias
                    where i.ItemID == itemId
                    orderby i.Order
                    select i).ToList();
        }
    }

    // this works fine
    public List<YouTubeVideo> GetYouTubeVideosForItem(int itemId)
    {
        using (var context = _db.CreateContext())
        {
            context.DeferredLoadingEnabled = false;

            return (from i in context.ItemMedias.OfType<YouTubeVideo>()
                    where i.ItemID == itemId
                    orderby i.Order
                    select i).ToList();
        }
    }
}

サービス インターフェイス:

[ServiceContract]
public interface IMediaService
{
    [OperationContract]
    [WebInvoke(
        Method = "GET",
        UriTemplate = "Media?itemId={itemId}",
        RequestFormat = WebMessageFormat.Json,
        ResponseFormat = WebMessageFormat.Json,
        BodyStyle = WebMessageBodyStyle.Bare
    )]
    List<ItemMedia> GetMediaForItem(int itemId);

    [OperationContract]
    [WebInvoke(
        Method = "GET",
        UriTemplate = "YouTubeVideos?itemId={itemId}",
        RequestFormat = WebMessageFormat.Json,
        ResponseFormat = WebMessageFormat.Json,
        BodyStyle = WebMessageBodyStyle.Bare
    )]
    List<YouTubeVideo> GetYouTubeVideosForItem(int itemId);
}

生成されたモデルは次のとおりです。

[global::System.Data.Linq.Mapping.TableAttribute(Name="dbo.ItemMedia")]
[global::System.Data.Linq.Mapping.InheritanceMappingAttribute(Code="media", Type=typeof(ItemMedia), IsDefault=true)]
[global::System.Data.Linq.Mapping.InheritanceMappingAttribute(Code="video", Type=typeof(YouTubeVideo))]
[global::System.Data.Linq.Mapping.InheritanceMappingAttribute(Code="image", Type=typeof(Image))]
public partial class ItemMedia : INotifyPropertyChanging, INotifyPropertyChanged
{

    private static PropertyChangingEventArgs emptyChangingEventArgs = new PropertyChangingEventArgs(String.Empty);

    private int _ID;

    private int _ItemID;

    private string _MediaType;

    private int _Order;

    private System.Nullable<System.DateTime> _AddedOn;

    private System.Nullable<int> _AddedBy;

    private System.Nullable<System.DateTime> _ChangedOn;

    private System.Nullable<int> _ChangedBy;

    private EntityRef<Item> _Item;

#region Extensibility Method Definitions
partial void OnLoaded();
partial void OnValidate(System.Data.Linq.ChangeAction action);
partial void OnCreated();
partial void OnIDChanging(int value);
partial void OnIDChanged();
partial void OnItemIDChanging(int value);
partial void OnItemIDChanged();
partial void OnMediaTypeChanging(string value);
partial void OnMediaTypeChanged();
partial void OnOrderChanging(int value);
partial void OnOrderChanged();
partial void OnAddedOnChanging(System.Nullable<System.DateTime> value);
partial void OnAddedOnChanged();
partial void OnAddedByChanging(System.Nullable<int> value);
partial void OnAddedByChanged();
partial void OnChangedOnChanging(System.Nullable<System.DateTime> value);
partial void OnChangedOnChanged();
partial void OnChangedByChanging(System.Nullable<int> value);
partial void OnChangedByChanged();
#endregion

    public ItemMedia()
    {
        this._Item = default(EntityRef<Item>);
        OnCreated();
    }

    [global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_ID", AutoSync=AutoSync.OnInsert, DbType="Int NOT NULL IDENTITY", IsPrimaryKey=true, IsDbGenerated=true)]
    public int ID
    {
        get
        {
            return this._ID;
        }
        set
        {
            if ((this._ID != value))
            {
                this.OnIDChanging(value);
                this.SendPropertyChanging();
                this._ID = value;
                this.SendPropertyChanged("ID");
                this.OnIDChanged();
            }
        }
    }

    [global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_ItemID", DbType="Int")]
    public int ItemID
    {
        get
        {
            return this._ItemID;
        }
        set
        {
            if ((this._ItemID != value))
            {
                if (this._Item.HasLoadedOrAssignedValue)
                {
                    throw new System.Data.Linq.ForeignKeyReferenceAlreadyHasValueException();
                }
                this.OnItemIDChanging(value);
                this.SendPropertyChanging();
                this._ItemID = value;
                this.SendPropertyChanged("ItemID");
                this.OnItemIDChanged();
            }
        }
    }

    [global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_MediaType", DbType="VarChar(10)", IsDiscriminator=true)]
    public string MediaType
    {
        get
        {
            return this._MediaType;
        }
        set
        {
            if ((this._MediaType != value))
            {
                this.OnMediaTypeChanging(value);
                this.SendPropertyChanging();
                this._MediaType = value;
                this.SendPropertyChanged("MediaType");
                this.OnMediaTypeChanged();
            }
        }
    }

    [global::System.Data.Linq.Mapping.ColumnAttribute(Name="[Order]", Storage="_Order", DbType="Int NOT NULL")]
    public int Order
    {
        get
        {
            return this._Order;
        }
        set
        {
            if ((this._Order != value))
            {
                this.OnOrderChanging(value);
                this.SendPropertyChanging();
                this._Order = value;
                this.SendPropertyChanged("Order");
                this.OnOrderChanged();
            }
        }
    }

    [global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_AddedOn", DbType="DateTime")]
    public System.Nullable<System.DateTime> AddedOn
    {
        get
        {
            return this._AddedOn;
        }
        set
        {
            if ((this._AddedOn != value))
            {
                this.OnAddedOnChanging(value);
                this.SendPropertyChanging();
                this._AddedOn = value;
                this.SendPropertyChanged("AddedOn");
                this.OnAddedOnChanged();
            }
        }
    }

    [global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_AddedBy", DbType="Int")]
    public System.Nullable<int> AddedBy
    {
        get
        {
            return this._AddedBy;
        }
        set
        {
            if ((this._AddedBy != value))
            {
                this.OnAddedByChanging(value);
                this.SendPropertyChanging();
                this._AddedBy = value;
                this.SendPropertyChanged("AddedBy");
                this.OnAddedByChanged();
            }
        }
    }

    [global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_ChangedOn", DbType="DateTime")]
    public System.Nullable<System.DateTime> ChangedOn
    {
        get
        {
            return this._ChangedOn;
        }
        set
        {
            if ((this._ChangedOn != value))
            {
                this.OnChangedOnChanging(value);
                this.SendPropertyChanging();
                this._ChangedOn = value;
                this.SendPropertyChanged("ChangedOn");
                this.OnChangedOnChanged();
            }
        }
    }

    [global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_ChangedBy", DbType="Int")]
    public System.Nullable<int> ChangedBy
    {
        get
        {
            return this._ChangedBy;
        }
        set
        {
            if ((this._ChangedBy != value))
            {
                this.OnChangedByChanging(value);
                this.SendPropertyChanging();
                this._ChangedBy = value;
                this.SendPropertyChanged("ChangedBy");
                this.OnChangedByChanged();
            }
        }
    }
            [global::System.Data.Linq.Mapping.AssociationAttribute(Name="Item_ItemMedia", Storage="_Item", ThisKey="ItemID", OtherKey="ID", IsForeignKey=true)]
    public Item Item
    {
        get
        {
            return this._Item.Entity;
        }
        set
        {
            Item previousValue = this._Item.Entity;
            if (((previousValue != value) 
                        || (this._Item.HasLoadedOrAssignedValue == false)))
            {
                this.SendPropertyChanging();
                if ((previousValue != null))
                {
                    this._Item.Entity = null;
                    previousValue.ItemMedias.Remove(this);
                }
                this._Item.Entity = value;
                if ((value != null))
                {
                    value.ItemMedias.Add(this);
                    this._ItemID = value.ID;
                }
                else
                {
                    this._ItemID = default(int);
                }
                this.SendPropertyChanged("Item");
            }
        }
    }

    public event PropertyChangingEventHandler PropertyChanging;

    public event PropertyChangedEventHandler PropertyChanged;

    protected virtual void SendPropertyChanging()
    {
        if ((this.PropertyChanging != null))
        {
            this.PropertyChanging(this, emptyChangingEventArgs);
        }
    }

    protected virtual void SendPropertyChanged(String propertyName)
    {
        if ((this.PropertyChanged != null))
        {
            this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

public partial class YouTubeVideo : ItemMedia
{

    private string _YouTubeVideoID;

#region Extensibility Method Definitions
partial void OnLoaded();
partial void OnValidate(System.Data.Linq.ChangeAction action);
partial void OnCreated();
partial void OnYouTubeVideoIDChanging(string value);
partial void OnYouTubeVideoIDChanged();
#endregion

    public YouTubeVideo()
    {
        OnCreated();
    }

    [global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_YouTubeVideoID", DbType="NVarChar(15)")]
    public string YouTubeVideoID
    {
        get
        {
            return this._YouTubeVideoID;
        }
        set
        {
            if ((this._YouTubeVideoID != value))
            {
                this.OnYouTubeVideoIDChanging(value);
                this.SendPropertyChanging();
                this._YouTubeVideoID = value;
                this.SendPropertyChanged("YouTubeVideoID");
                this.OnYouTubeVideoIDChanged();
            }
        }
    }
}

public partial class Image : ItemMedia
{

    private string _ImageName;

    private string _ImageData;

#region Extensibility Method Definitions
partial void OnLoaded();
partial void OnValidate(System.Data.Linq.ChangeAction action);
partial void OnCreated();
partial void OnImageNameChanging(string value);
partial void OnImageNameChanged();
partial void OnImageDataChanging(string value);
partial void OnImageDataChanged();
#endregion

    public Image()
    {
        OnCreated();
    }

    [global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_ImageName", DbType="NVarChar(MAX)")]
    public string ImageName
    {
        get
        {
            return this._ImageName;
        }
        set
        {
            if ((this._ImageName != value))
            {
                this.OnImageNameChanging(value);
                this.SendPropertyChanging();
                this._ImageName = value;
                this.SendPropertyChanged("ImageName");
                this.OnImageNameChanged();
            }
        }
    }

    [global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_ImageData", DbType="NVarChar(MAX)")]
    public string ImageData
    {
        get
        {
            return this._ImageData;
        }
        set
        {
            if ((this._ImageData != value))
            {
                this.OnImageDataChanging(value);
                this.SendPropertyChanging();
                this._ImageData = value;
                this.SendPropertyChanged("ImageData");
                this.OnImageDataChanged();
            }
        }
    }
}
4

1 に答える 1