我有一些业务对象(由开发人员编写)和一些存储过程(由数据库管理员编写)。
有没有人能推荐一个好的对象映射器来处理这种设置。
我尝试了Codesmith和NHibernate,但遇到了问题。 我不介意我的ORM是免费还是付费的。
我有一些业务对象(由开发人员编写)和一些存储过程(由数据库管理员编写)。
有没有人能推荐一个好的对象映射器来处理这种设置。
我尝试了Codesmith和NHibernate,但遇到了问题。 我不介意我的ORM是免费还是付费的。
琐碎的事情:
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");
public interface IDynamicParameters
{
void AddParameters(IDbCommand command);
}
当实现这个接口时,您可以告诉Dapper您希望添加到命令中的参数。这样可以支持表值参数和其他特定于数据库的功能。
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。
根据数据库,Entity Framework或NHibernate可能是您最好的选择(链接中有示例)。
LINQ to SQL 设计器将在 DataContext 对象上作为方法提供类型安全的存储过程。您可以将其映射到对象以进行 CRUD 操作。
事实上,我正在做这件事的中间阶段。
既然你有一个DBA编写存储过程,我认为最好的做法是与他密切合作,找出如何将表映射到对象,以及如何构建数据库使其与你的领域模型相匹配。存储过程并没有什么问题,只需要开发人员和DBA之间进行密切协作。
理想情况下,这位DBA应该是你项目团队的一部分...
我喜欢 Entity Framework 目前处理存储过程的方式。你可以将存储过程与实体的增删改查操作关联起来,它甚至会检测哪些存储过程与你的实体属性匹配。目前唯一的缺点是,如果你将一个存储过程与一个实体关联起来,你必须将所有的增删改查操作都与一个存储过程关联起来。
这篇 EF Sproc article 有一些很好的示例,展示了如何在 EF 中使用存储过程,并提供了一些非常好的扩展方法。
更新: 我更偏向于使用 Linq to SQL,但我会再次审视你对 NHibernate 的假设。特别是,我怀疑它会强制列顺序,因为它配置了列名(参见http://nhibernate.info/blog/2008/11/23/populating-entities-from-stored-procedures-with-nhibernate.html)。它还支持一些我不知道如何在 Linq to SQL 中实现的功能:http://nhibernate.info/blog/2008/11/23/populating-entities-with-associations-from-stored-procedures-with-nhibernate.html。请注意,我并不是指 Linq to SQL 不支持最后一个功能,只是我不知道如何实现 ;)
现在你可以尝试使用Nfinity.Data,它具有对存储过程的强类型支持,包括表值参数(TVP)和输出参数。要读取任何结果,您需要手动访问阅读器(它提供了一个阅读器抽象层)。
我不太相信NHibernate或EF将实体映射到存储过程的想法,因为它们的内部工作方式是不确定的,即无法在运行时以任何方式进行验证。通过像上面那样的阅读器,在代码中完成所有操作更具声明性。
sp_GetUserById
进行调试。视图模型、控制器和服务都在做它们应该做的事情并通过了测试(你有测试,对吧?)。你检查数据,看起来没问题。"这个......" 你喃喃自语,再次加载 SSMS。它在那里!不仅存储过程中有业务逻辑,而且与上个月发布的新功能冲突。祝你好运,逃避责任吧! - CaptainMarvel