1

複数のプラットフォームから注文情報を取得する .net 4 をターゲットとする Windows アプリに取り組んでいます。データをローカル データベースに保存する必要があり、LINQ to SQL を使用することにしました。現在、注文クラスには、各プラットフォームで送信されたデータを処理するためのかなりの量のコードがあるため、デコレータを使用して属性を追加しています。 Visual Studio でデザイナーを使用するのではなく、クラスに。

ほとんどの場合は機能しているようですが、注文の DB を照会すると、メインの注文データのみが正常に返され、Items EntitySet を列挙しようとすると、「指定されたキャストが無効です」がスローされます。例外。プログラムは、注文を Orders テーブルに正しく挿入し、注文明細/アイテムを OrdersLines テーブルに正しく挿入します。また、OrdersLines テーブルを読み取り、正しく設定された OrderLine オブジェクトを返します。

データベース レイアウトOrders.orderID にリンクされた OrdersLines に外部キー制約があります。

クラス:

[Table(Name = "Orders")]
public class Order
{
    [Column(Name="orderID",IsPrimaryKey=true, IsDbGenerated=false)]
    public string OrderID;
    [Column(Name = "sourceID")]
    public int SourceID;
    [Column(Name = "statusID")]
    public int StatusID = 1;
    [Column(Name = "externalOrderID")]
    public string ExternalOrderID;
    [Column(Name = "deliveryName")]
    public string Recipient = "";
    [Column(Name = "deliveryCompany")]
    public string Company = "";
    [Column(Name = "deliveryAddress1")]
    public string Address1 = "";
    [Column(Name = "deliveryAddress2")]
    public string Address2 = "";
    [Column(Name = "deliveryAddress3")]
    public string Address3 = "";
    [Column(Name = "deliveryTown")]
    public string Town = "";
    [Column(Name = "deliveryCounty")]
    public string County = "";
    [Column(Name = "deliveryCountry")]
    public string Country = "";
    [Column(Name = "deliveryCountryISO")]
    public string CountryISO = "";
    public Country RMCountryData;
    [Column(Name = "deliveryPostcode")]
    public string Postcode = "";
    public Int64 TotalWeight = 0;
    public ShippingType ShippingType = ShippingType.Standard;
    public ShippingDestination ShippingDestination = ShippingDestination.International;
    [Column(Name = "email")]
    public string Email = "";

    private EntitySet<OrderLine> _Items = new EntitySet<OrderLine>();
    [Association(Name = "FK_OrdersLines_Orders", Storage = "_Items")]
    public EntitySet<OrderLine> Items
    {
        set
        {
            this._Items.Assign(value);
        }
        get
        {
            return this._Items;
        }
    }

    public Order() {  }

    public void Save()
    {
        OrderDataContext context = new OrderDataContext(String.Format(Settings.Default.ConnectionString, Settings.Default.DBUser, Settings.Default.DBPassword, Settings.Default.DBServer, Settings.Default.DBName));
        context.Log = Console.Out;
        var query = from o in context.Order where o.OrderID.Equals(this.OrderID) select o;
        var line = from l in context.OrderLine where l.OrderID.Equals(this.OrderID) select l;

        if (query.Count() == 0)
        {
            context.Order.InsertOnSubmit(this);
            context.SubmitChanges();
        }
        else
        {
            foreach (var customerOrder in query)
            {
                Console.WriteLine(customerOrder.OrderID);
                foreach (var orderItem in customerOrder.Items)
                {
                    Console.WriteLine(orderItem.Name);
                }
            }
        }
    }
}

[Table(Name = "OrdersLines")]
public class OrderLine
{
    [Column(Name = "localLineID", IsPrimaryKey = true, IsDbGenerated = true)]
    public int LocalLineID;
    [Column(Name = "orderID")]
    public string OrderID;
    [Column(Name = "lineID")]
    public Int64 LineID;
    public Int64 ProductID;
    [Column(Name = "sku")]
    public Int64 SKU;
    [Column(Name = "name")]
    public string Name;
    [Column(Name = "quantity")]
    public int Quantity;
    [Column(Name = "weight")]
    public Int64 Weight;

    public OrderLine() { }

    public OrderLine(Order Parent, Int64 SKU, Int64 LineID, string Name, int Quantity)
    {
        this.OrderID = Parent.OrderID;
        this.LineID = LineID;
        this.ProductID = 0;
        this.SKU = SKU;
        this.Name = Name;
        this.Quantity = Quantity;
        this.Weight = 0;
    }
}

public partial class OrderDataContext : DataContext
{
    public Table<Order> Order;
    public Table<OrderLine> OrderLine;

    public OrderDataContext(String connString) : base(connString) { }
}

例外は、「foreach (var orderItem in customerOrder.Items)」の行でスローされます。

スタックトレース:

at System.Data.Linq.IdentityManager.StandardIdentityManager.SingleKeyManager`2.TryCreateKeyFromValues(Object[] values, V& v)
at System.Data.Linq.IdentityManager.StandardIdentityManager.IdentityCache`2.Find(Object[] keyValues)
at System.Data.Linq.CommonDataServices.DeferredSourceFactory`1.TryGetCachedObject(Object[] keyValues, T& cached)
at System.Data.Linq.CommonDataServices.DeferredSourceFactory`1.Execute(Object instance)
at System.Data.Linq.EntitySet`1.Load()
at System.Data.Linq.EntitySet`1.GetEnumerator()
at System.Linq.SystemCore_EnumerableDebugView`1.get_Items()
4

1 に答える 1

0

あなたのデータベース レイアウト (SQL Server Management Studio のスクリーンショット?) に表示されているものから、"weight" 列と "lineID" 列は "Allow Nulls" として定義されています。

しかし、OrderLineあなたが投稿したクラス定義には、LineIDWeightプロパティはありませんNullable:

[Table(Name = "OrdersLines")]
public class OrderLine
{
    // ...
    [Column(Name = "lineID")]
    public Int64 LineID;
    // ...
    [Column(Name = "weight")]
    public Int64 Weight;

Linq2SQL は確かにこれらのプロパティが次のようになることを期待しておりNullable、その理由を説明できSpecified cast is not validます。

代わりにこのコードを使用してみてください:

[Table(Name = "OrdersLines")]
public class OrderLine
{
    // ...
    [Column(Name = "lineID")]
    public Int64? LineID;
    // ...
    [Column(Name = "weight")]
    public Int64? Weight;

編集

orderIdisnvarchar(30)localLineIdisにも気づきましたint。結合 SQL ステートメントの生成中に Linq2SQL で問題が発生する可能性があり、それらを同じ型に設定することは確かに価値があります。

最後に、それが問題でした:

[Association(Name = "FK_OrdersLines_Orders", Storage = "_Items")]

次のようになります。

[Association(Name = "FK_OrdersLines_Orders", Storage = "_Items", OtherKey = "OrderID")]
于 2013-10-25T23:09:03.293 に答える