我有Business对象(DEVELOPERS WRITE)和一些SPROCS(DBA WRITE)
任何人都可以推荐一个好的对象映射器来处理这种设置。
我尝试使用codesmith和nhibernate并遇到麻烦。我不介意我的ORM是免费的还是付费的。
答案 0 :(得分:7)
SubSonic对sprocs有很好的支持。它将每个都包装在一个帮助器方法中,如果需要,您可以从结果中检索强类型集合或实体。我在this blog post中展示了一种方法。只要您的sproc返回与SELECT * FROM TableName相同的模式,它就可以与您的SubSonic实体一起使用。
就基于db生成类而言,SubSonic会生成部分类,因此您可以根据需要扩展它们。您还可以从SubSonic生成的类到您的实际模型进行映射。
答案 1 :(得分:5)
Subsonic有一个灵活的解决方案:
class CustomerOrder {
private string productName;
public string ProductName {
get { return productName; }
set { productName = value; }
}
private int total;
public int Total {
get { return total; }
set { total = value; }
}
}
然后:
List<CustomerOrder> orders = Northwind.SPs.CustOrderHist("ALFKI")
.ExecuteTypedList<CustomerOrder>();
Subsonic是一种坚固的“瑞士军刀”式ORM。
答案 2 :(得分:5)
免责声明:我是Dapper的作者。
如果您正在寻找一个简单的对象映射器来处理映射过程到业务对象Dapper是一个很好的选择。
请记住,它没有“图形管理”,“身份图”等。它提供了一个裸机,完整解决方案,涵盖了其他ORM没有的许多场景。
尽管如此,它提供了最快的对象物化器之一,在某些benchmarks中可以比EF快10倍甚至比亚音速快100倍。
琐碎:
create proc spGetOrder
@Id int
as
select * from Orders where Id = @Id
select * from OrderItems where OrderId = @Id
可以使用以下内容进行映射:
var grid = cnn.QueryMultiple("spGetOrder", new {Id = 1}, commandType: CommandType.StoredProcedure);
var order = grid.Read<Order>();
order.Items = grid.Read<OrderItems>();
此外,您还支持:
例如:
create proc spGetOrderFancy
@Id int,
@Message nvarchar(100) output
as
set @Message = N'My message'
select * from Orders join Users u on OwnerId = u.Id where Id = @Id
select * from OrderItems where OrderId = @Id
return @@rowcount
可以映射:
var p = new DynamicParameters();
p.Add("Id", 1);
p.Add("Message",direction: ParameterDirection.Output);
p.Add("rval",direction: ParameterDirection.ReturnValue);
var grid = cnn.QueryMultiple("spGetOrder", p, commandType: CommandType.StoredProcedure);
var order = grid.Read<Order,User,Order>((o,u) => {o.Owner = u; return o;});
order.Items = grid.Read<OrderItems>();
var returnVal = p.Get<int>("rval");
var message = p.Get<string>("message");
最后,dapper还允许自定义参数实现:
public interface IDynamicParameters
{
void AddParameters(IDbCommand command);
}
实现此界面时,您可以告诉dapper您希望添加到命令中的参数。这允许您支持Table-Valued-Params和其他DB特定功能。
答案 3 :(得分:2)
根据数据库Entity Framework,或NHibernate可能是您的最佳选择(链接中的示例)。
答案 4 :(得分:1)
LINQ to SQL设计器将为您提供类型安全的sprocs作为DataContext对象的方法。您可以非常轻松地将这些映射到CRUD操作的对象。
事实上,我正在做这件事。
答案 5 :(得分:1)
既然你有一个DBA编写sprocs,我认为最好的办法是与他密切合作,弄清楚如何将表映射到对象,以及如何构建数据库以使其工作与您的域模型。 sprocs没有任何问题,它们只需要开发人员和DBA之间的密切合作。
理想情况下,有问题的DBA是您项目团队的一部分......
答案 6 :(得分:0)
我看到的主要问题是,通过使用SP,您将自动失去使用ORM时获得的大量灵活性,特别是在检索信息时。因此,我相信您将无法使用大多数ORM的所有功能。
例如,如果你使用linq2sql,你将拥有很多SP的包装器。您还可以将生成的实体的插入,删除和更新映射到存储过程。你松散的地方在于检索信息,因为查询现在已经修复了(你可能会检索到比需要更多的信息,即额外的列 - 或创建大量的SP)以及延迟加载。
更新:我更像是一个linq2sql家伙,但我会再看看你对NHibernate所做的假设。特别是,我怀疑它会强制列顺序,因为它配置了列名称(请参阅http://nhibernate.info/blog/2008/11/23/populating-entities-from-stored-procedures-with-nhibernate.html)。它还支持我不知道如何处理linq2sql:http://nhibernate.info/blog/2008/11/23/populating-entities-with-associations-from-stored-procedures-with-nhibernate.html。注意,我不是说linq2sql不支持最后一个,只是我不知道如何;)
答案 7 :(得分:0)
我喜欢Entity Framework现在处理sprocs的方式。您可以将sprocs与实体的crud操作相关联,甚至可以检测哪些sprocs与实体的属性匹配。现在一个很大的缺点是如果你将一个sproc与一个实体相关联,你必须将所有crud操作与一个sproc关联起来。
这个EF Sproc article有一些很好的例子,说明如何在EF中使用sprocs,并且还有一些非常好的扩展方法。
答案 8 :(得分:0)
现在您可以尝试 Nfinity.Data,它对存储过程提供强类型支持,包括表值参数 (TVP) 和输出参数。要读取任何结果,您需要手动访问读取器(它为此提供了读取器抽象)。
我不相信 NHibernate 或 EF 将实体映射到存储过程的想法,因为它们的内部工作是不确定的,即,在运行时之前无法以任何方式进行验证。通过上面的阅读器,在代码中完成所有事情更具声明性。