通过 NHibernate 调用存储过程

5

我需要通过nhibernate调用存储过程,但我不知道如何操作。 我有一个简单的存储过程:

CREATE PROCEDURE InsertDoc 
    @Name nvarchar(50),   
    @Author nvarchar(50),
    @Link nvarchar(50) 
AS 
    INSERT INTO documents(name, date, author, doclink) 
    VALUES(@Name, CURRENT_TIMESTAMP, @Author, @Link)

我在我的代码中尝试了这个:

public class documents
{
    public int id;
    public string name;
    public DateTime date;
    public string author;
    public string doclink;

    public void CreateDocuments(String n,String l,String u)
    {
        documents exSample = new documents();
        exSample.name = n;
        exSample.date = DateTime.Now;
        exSample.author = u;
        exSample.doclink = l;

        using (ISession session = OpenSession())
        using (ITransaction transaction = session.BeginTransaction())
        {
            //Session.CreateSQLQuery("EXEC :sp_name :start_date :end_date").SetString("sp_name", <>;)
            session.CreateSQLQuery("EXEC InsertDoc @Name = N'" + exSample.name + "',@Author = N'" + exSample.author + "',@Link = N'" + exSample.doclink + "'");
            // session.Save(exSample);
            transaction.Commit();
        }
    }

    public ISessionFactory factory;

    public ISession OpenSession()
    {
        if (factory == null)
        {
            Configuration conf = new Configuration();
            conf.AddAssembly(Assembly.GetCallingAssembly());
            factory = conf.BuildSessionFactory();
        }
        return factory.OpenSession();
    }
}

我调用存储过程。

session.CreateSQLQuery("EXEC InsertDoc @Name = N'" + exSample.name + "',@Author = N'" + exSample.author + "',@Link = N'" + exSample.doclink + "'");

在我的映射文件中,我有以下设置:
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" auto-import="true" namespace="WebApplication1" assembly="WebApplication1">
  <class name="WebApplication1.documents" table="documents" lazy="false">
    <id name="id" access="field">
      <generator class="native" />
    </id>
    <property name="name" access="field" column="name" type="String"/>
    <property name="date" access="field" column="date" type="date"/>
    <property name="author" access="field" column="author" type="String"/>
    <property name="doclink" access="field" column="doclink" type="String"/>
  </class>
</hibernate-mapping>

帮我解决这个问题或者给我提供有用的链接。


你遇到了什么错误? - Leniel Maccaferri
我认为你没有理解NHibernate作为ORM的重点。你可以像你已经注释掉的那一行代码一样实例化documents并调用Save()方法。 - Michael
2个回答

3

这是一个实体映射的示例,它使用存储过程来插入、更新和删除数据库行:

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" schema="dbo"
               assembly="MyAssembly"
               namespace="MyAssembly.MyNamespace">

  <class name="MyEntity" table="my_entity" lazy="false">
    <id name="MyId" column="my_id" type="Int64">
      <generator class="native" />
    </id>
    <property name="Name" type="string" column="name" />
    <property name="Comment" type="string" column="comment" />

    <sql-insert xml:space="preserve">
      DECLARE @my_id  bigint
      EXECUTE dbo.InsertMyEntity @name = ?, @comment = ?, @my_id = @my_id OUT
      SELECT  @my_id
    </sql-insert>
    <sql-update xml:space="preserve">
      EXECUTE dbo.UpdateMyEntity @name = ?, @comment = ?, @my_id = ?
    </sql-update>
    <sql-delete xml:space="preserve">
      EXECUTE dbo.DeleteMyEntity @my_id = ?
    </sql-delete>
  </class>
</hibernate-mapping>

通过这个映射,你可以使用ISession.SaveISession.UpdateISession.Delete方法来管理你的实体,并使NHibernate一级实体缓存与数据库保持同步。
祝好, Gerke。

1
我们应该把这个文件放在哪里? - Hudhaifa Yoosuf
这是一个NHibernate XML映射文档,通常被定义为您的NHibernate项目中的“嵌入式资源”项。 - Gerke Geurts
@GerkeGeurts 你得到了我的点赞,因为你没有发布容易受攻击的代码,但是你能否演示一下如何通过ClassMapping或类似的方式来实现呢? - Daniel Santos
@GerkeGeurts 你因为没有发布容易受攻击的代码而得到了我的点赞,但你能否也演示一下如何通过ClassMapping或类似的方式来实现呢? - undefined

2

看起来您少了一个Query.executeUpdate(),所以

session.CreateSQLQuery("EXEC InsertDoc @Name = N'" + exSample.name + "',@Author = N'" + exSample.author + "',@Link = N'" + exSample.doclink + "'").executeUpdate();

这应该是可行的,但最好以编程方式绑定变量。


5
不应该点赞这个... 构建动态 SQL 字符串不是一个好的解决方案。 - Jansky
你正在请求进行SQL注入攻击。相反,像@GerkeGeurts一样,准备一个语句,然后将值传递给它。 - Daniel Santos
你正在要求进行SQL注入攻击。相反,应该准备一个语句,然后将值传递给它,就像@GerkeGeurts所做的那样。 - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接