开发者

NHibernate: Using slightly different hbm mapping files depending on context

One of my applications is a public website, the other is an intranet. The public website runs using a limite开发者_StackOverflowd security user that must access a certain table through a view, whereas the intranet can access the table itself.

This seems like it would be quite simple to setup using Fluent NHibernate. In my ClassMap I could do a check like this:

public class MyEntityClassMap : ClassMap<MyEntity>
{
     public MyEntityClassMap()
     {
         if (NHibernateConfig.Current.Context == "intranet")
            Table("t_MyEntity");
         else
            Table("v_MyEntity_pub");
         ... etc
     }
}

Is there a simple way of doing this for embedded hbm files? The only method I can think of would be to have two copies of the hbm file, which would be confusing and far from ideal.

Is there perhaps a better way of achieving the same result?


Actually what you ask it is possible. You can actually access the embedded XML files and alter their content before the SessionFactory is build (on Application Start).

Assuming your will choose to reference the "t_MyEntity" in your entities by default here is how you can dynamically change this reference when you want to reference the "v_MyEntity_pub" table instead (the code may not work as it is but you will get the idea):

    NHibernate.Cfg.Configuration cfg = new NHibernate.Cfg.Configuration();
    cfg.AddAssembly(ASSEMBLYNAME);

    if (NHibernateConfig.Current.Context != "intranet") //this is how you have stated you distinguish the intranet application from the other one.
    {
        string[] resourcesNames = assembly.GetManifestResourceNames();
        foreach (string resourceName in resourcesNames)
        {
            StreamReader sr = new  StreamReader(assembly.GetManifestResourceStream(resourceName));
            string resourceContent = sr.ReadToEnd();
            resourceContent = resourceContent.Replace("t_MyEntity", "v_MyEntity_pub");
            cfg.AddXmlString(resourceContent);
        }
     }

     ISessionFactory sessionFactory = cfg.BuildSessionFactory();

The above code should be executed only once for the lifetime of your application and only for the intranet application.


Although this is perhaps not the most helpful answer to your problem, I don't believe that this is possible in a mapping file. I also don't think that two hbm files would work for the same name, as it would be unable to distinguish between the two, you would instead have to have two identical objects each with slightly different names and mapping files. Which as you said in your question, would be completely confusing and ideal would simply be a spot on the horizon that you were hoping to, someday, reach.

Why is it that can't access everything directly through the view? I'm assuming there is no writing involved in this process? Is there any way you can change this method of accessing data while still maintaining your security?

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜