我有一个复杂的C#对象,需要在数据库中的多个表(大约12个)中保存:
class Foo
{
public Guid FooId { get; set; }
public Bar[] Bars { get; set; }
}
class Bar
{
public Guid BarId { get; set; }
public Guid FooId { get; set; }
public Baz[] Bazs { get; set; }
}
class Baz
{
public Guid BazId { get; set; }
public Guid BarId { get; set; }
// And so on ...
}
问题:
Foo
的实例)作为输入发送到存储过程的最佳方法是什么?Foo
,Bar
和Baz
表与其父ID相关联(例如Bar
需要其父FooId
})?答案 0 :(得分:3)
以下是您可能想要考虑建模的大致轮廓。这不是一个完整的骨架(因为你可能想要稍微使用范围),但应该给出一个大致的想法。我在几个项目中使用了类似的模型。
如果这些类都遵循相同类型的数据模型,则可以对这些类进行抽象。
class Foo
{
public Guid FooId { get; private set; } // Only allow the object to define its Id.
public List<Bar> Bars { get; set; } // Use a dynamic storage object.
private bool Deleted { get; set; } // Monitors if the object has been deleted in the DB.
public Foo()
{
this.FooId = Guid.Empty;
this.Deleted = false;
Bars = new List<Bar>();
}
public Foo(Guid fooId)
{
this.Deleted = false;
this.FooId = fooId;
LoadFromDatabase();
Bars = new List<Bar>();
LoadBarsFromDatabase();
}
private void LoadFromDatabase()
{
// Read from DB, set local variables...
}
private void LoadBarsFromDatabase()
{
// Psuedocode to load all Bars.
foreach (var barData in barIdsLinkedToFooTable.Rows)
{
Bars.Add(new Bar(this, barData["barId"]));
}
}
public void SaveToDatabase()
{
// If FooId is Guid.Empty, the record is new.
// You may also want to consider the Deleted property value.
// Either generate the new Guid first or let SQL do it for you in your SP.
// Save Foo to DB with stored proc.
// Save Bars.
foreach (var bar in Bars)
{
bar.SaveToDatabase();
}
}
public void Delete()
{
// Delete via a stored proc.
// Might be a good idea to set SQL to cascade the delete,
// this way all the children will be deleted automatically.
this.Deleted = true;
}
}
class Bar
{
public Guid BarId { get; private set; } // Only allow the local object to generate Id.
public Foo ParentFoo { get; set; } // Store a reference to the parent.
public List<Baz> Bazs { get; set; } // Use a dynamic storage object.
private bool Deleted { get; set; } // Monitors if the object has been deleted in the DB.
public Bar(Foo parentFoo)
{
// New Bar object.
this.BarId = Guid.Empty;
this.ParentFoo = parentFoo;
this.Bazs = new List<Baz>();
this.Deleted = false;
}
public Bar(Foo parentFoo, Guid barId)
{
// Create from existing object.
this.Deleted = false;
this.BarId = barId;
this.ParentFoo = parentFoo;
LoadFromDatabase();
Bazs = new List<Baz>();
LoadBazsFromDatabase();
}
/* DB methods for load, save, and delete similar to above. */
}
答案 1 :(得分:1)
理论上,您应该将复杂对象序列化为XML并将其作为参数传递给存储过程。
在存储过程代码中,您可以查询此XML。 TSQL Parse XML in Stored Procedure
结果你可以达到很高的性能,但这种方式可能变得难以维护,因为存储过程必须知道如何处理复杂的对象。