質問

私は新しい型を定義しようとしていると多くの幸運それらの中にリストを使用してについての情報を見つけることがありませんでした。基本的に私の新しいタイプは、二つのリストが含まれます、と言うのxとyタイプのたSqlSingle(ユーザー定義型は、C#で書かれている)ことも可能である。この?

することができます

あなたは、SQL Server 2008の列にarbitary長さの2つのリストをシミュレートすることについて行くことになっているかいないか?

私はおそらくこのことについて間違った道を進んだが、それは私が現時点での考えることができる最善のアプローチです。すべてのヘルプは非常に高く評価されます。

役に立ちましたか?

解決

CLR型は不変であるべき構造体、ですが、あなたは可変性のために非常に説得力のある理由を持っていない場合List<T>がより良い選択となるので、 -

あなたはCLR UDTにReadOnlyCollection<T>を使用することができます。あなたはどちらの場合にも知っておく必要があると、SQLはリスト自体を使用する方法を知っていないということです。あなたは純粋な.NETで行うことができるようになるようにあなたは、単に、公共IList<T>またはIEnumerable<T>としてリスト型を公開し、あなたの陽気な方法にすることはできません。

一般的にこの問題を回避する方法は、個々のリスト項目で取得するためにCountプロパティといくつかのメソッドを公開することになります。

あなたは独立して、それを管理し、必要であればSQLでそれを周りに渡すことができるようにまた、この場合には、代わりにSqlSingleインスタンスの2つの別々のリストを維持し、私は、単一のポイントを表現するための追加のタイプを作成します。

[Serializable]
[SqlUserDefinedType(Format.Native)]
public struct MyPoint
{
    private SqlSingle x;
    private SqlSingle y;

    public MyPoint()
    {
    }

    public MyPoint(SqlSingle x, SqlSingle y) : this()
    {
        this.x = x;
        this.y = y;
    }

    // You need this method because SQL can't use the ctors
    [SqlFunction(Name = "CreateMyPoint")]
    public static MyPoint Create(SqlSingle x, SqlSingle y)
    {
        return new MyPoint(x, y);
    }

    // Snip Parse method, Null property, etc.
}

主なタイプは次のようになります:

[Serializable]
[SqlUserDefinedType(Format.UserDefined, IsByteOrdered = true, MaxByteSize = ...)]
public struct MyUdt
{
    // Make sure to initialize this in any constructors/builders
    private IList<MyPoint> points;

    [SqlMethod(OnNullCall = false, IsDeterministic = true, IsPrecise = true)]
    public MyPoint GetPoint(int index)
    {
        if ((index >= 0) && (index < points.Count))
        {
            return points[index];
        }
        return MyPoint.Null;
    }

    public int Count
    {
        get { return points.Count; }
    }
}

あなたはSQLはすべての点列を取得できるようにする必要がある場合は、あなたにもシーケンス型に列挙メソッドを追加することができます:

[SqlFunction(FillRowMethodName = "FillPointRow",
    TableDefinition = "[X] real, [Y] real")]
public static IEnumerable GetPoints(MyUdt obj)
{
    return obj.Points;
}

public static void FillPointRow(object obj, out SqlSingle x, out SqlSingle y)
{
    MyPoint point = (MyPoint)obj;
    x = point.X;
    y = point.Y;
}
あなたはそれが動作しない、それはIEnumerable<T>を使用することが可能だと思うおよび/または静的の代わりにインスタンスメソッドを使用しますが、でもしようと気にしないかもしれません。

あなたはSQL Serverの結果の型を使用することができる方法があります:

DECLARE @UDT MyUdt
SET @UDT = <whatever>

-- Will show the number of points
SELECT @UDT.Count

-- Will show the binary representation of the second point
SELECT @UDT.GetPoint(1) AS [Point]

-- Will show the X and Y values for the second point
SELECT @UDT.GetPoint(1).X AS [X], @UDT.GetPoint(1).Y AS [Y]

-- Will show all the points
SELECT * FROM dbo.GetPoints(@UDT)

希望これは正しい軌道に乗ってあなたを得ることができます。 UDTのはかなりときに、リスト/シーケンスデータと、彼らしている取引を管理するために複雑になることができます。

また、あなたは明らかに直列化メソッド、ビルダー方法、集計方法などを追加する必要がありますので注意してください。これはかなりの試練ことができます。必ずこれを使用すると、UDT列の追加を開始したら、あなたが間違った選択をしたことを認識した場合に変更を加えることが非常に困難な場合がありますので、あなたが、中に行きたい方向が実際にあることを確認します。

他のヒント

は、通常、正規化され説明するようにリスト - 、項目ごとに1行で別々のテーブルに格納されている - はなく単一の列にそれらを詰め込むしようとするよりも。あなたが達成しようとしているのかについての詳細情報を共有することができれば、多分私達はより多くの援助を提供することができます。

編集 - 提案テーブル構造ます:

-- route table--
route_id      int   (PK)
route_length  int (or whatever)
route_info    <other fields as needed>

-- waypoint table --
route_id      int      (PK)
sequence      tinyint  (PK)
lat           decimal(9,6)
lon           decimal(9,6)
waypoint_info <other fields as needed>
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top