是否可以使用流畅的nhibernate映射设置SQL Server列的描述?

时间:2010-05-14 05:08:46

标签: .net sql-server nhibernate fluent-nhibernate

我正在使用流畅的nhibernate映射来生成我的MS SQL Server数据库。

我希望能够将列的描述设置为这一代的一部分。

3 个答案:

答案 0 :(得分:4)

不,这是不可能的。描述是Microsoft特定的元数据属性,NHibernate和Fluent NHibernate都尽可能保持数据库不可知。

你可以使用SqlInsert映射来完成它,但它不会很好。

答案 1 :(得分:1)

这并非不可能,但Fluent NHibernate和NHibernate本身并没有提供这样的API。

在NHibernate创建数据库之后,您必须编写一些代码来检查生成的数据库结构,然后编写好的旧SQL语句来自行设置描述。

也许您可以创建一个Fluent NHibernate“约定”来记录创建的表以及哪些列,然后您可以轻松编写手动设置描述的代码。
(如果需要的话,我会为你写一些代码。)

答案 2 :(得分:1)

如果确实需要这个,可以将列描述映射到“holder”表,该表将存储保存/加载的描述。此holder表将需要SchemaName,TableName,ColumnName和Description的列。在此表上添加一个TRIGGER,它将执行SQL Server的sp_addextendedproperty (Transact-SQL)sp_dropextendedproperty (Transact-SQL)命令,以便在适当的schema.table.column中添加/删除描述。

表格如下:

DescriptionHolder
SchemaName   sysname
TableName    sysname
ColumnName   sysname
Description  varchar(7500) --or nvarchar(3750)

触发器就像:

CREATE TRIGGER trigger_DescriptionHolder ON DescriptionHolder
   INSTEAD OF INSERT,UPDATE,DELETE
AS 
SET NOCOUNT ON


IF EXISTS (SELECT * FROM INSERTED)
BEGIN
    --handles INSERTS and UPDATEs
    --loop begin here over INSERTED
        EXECUTE sp_addextendedproperty N'MS_Description', <INSERTED.Description>
            ,N'SCHEMA' , <INSERTED.SchemaName>
            ,N'TABLE'  , <INSERTED.TableName>
            ,N'COLUMN' , <INSERTED.ColumnName>
    --loop end here


END
ELSE IF EXISTS(SELECT * FROM DELETED)
BEGIN
    --handles DELETEs
    --loop begin here over DELETED
    EXECUTE sp_dropextendedproperty ...
    --loop end here

END

如果您担心桌子与实际列描述不同步,可以将其添加到触发器的末尾:

IF EXISTS (SELECT 1 AS x --h.SchemaName,h.TableName,h.ColumnName
               FROM DescriptionHolder h 
               WHERE NOT EXISTS (SELECT 1  
                                     from sys.extended_properties p
                                         inner join sys.objects   o ON p.major_id=o.object_id
                                         inner join sys.schemas   s ON o.schema_id=s.schema_id
                                         inner join sys.columns   c ON o.object_id=c.object_id and p.minor_id=c.column_id
                                     where h.SchemaName=s.name AND h.TableName=o.name AND h.ColumnName=c.name)
           UNION ALL
           select 2 AS x --s.name AS SchemaName,o.name AS TableName,c.name AS ColumnName
               from sys.extended_properties p
                   inner join sys.objects   o ON p.major_id=o.object_id
                   inner join sys.schemas   s ON o.schema_id=s.schema_id
                   inner join sys.columns   c ON o.object_id=c.object_id and p.minor_id=c.column_id
               where p.class=1 and p.Name='MS_Description'
                   AND not exists (SELECT 1 FROM DescriptionHolder h WHERE s.name=h.SchemaName AND o.name=h.TableName AND c.name=h.ColumnName)
          )
    BEGIN
        RAISERROR('sys.extended_properties and DescriptionHolder do not match',16,1)
        ROLLBACK
        RETURN
    END

如果DescriptionHolder与数据库中的实际列描述不是100%同步,则此代码将回滚并中止触发器。