简体   繁体   中英

Fluent NHibernate map sql Count() column

I got a small problem here where I need to map a count() column in NHibernate. I'm really bad at NHibernate, but this is the task I got that I need to solve.

Sorry for the Swedish in the code I will post here, it's an old database that originally only was in Swedish. But really, you only need to look at the first row. But I post the whole thing just in case.

SELECT COUNT(Matpunkt.id_matpunkt) AS [Count], 
            f.ID_Företag,
            f.Namn,
            f.Adress,
            f.Postnummer,
            f.Postadress,
            f.Tele,
            f.Orgnummer,
            f.Typ,
            f.Logo,
            f.Fax,
            f.Mallkatalog,
            f.Tidszon,
            u.Ansvarigtkontor AS [AnsvKontor]

            FROM Matpunkt 
            INNER JOIN MatpunktInstrumentParameter ON Matpunkt.id_matpunkt = MatpunktInstrumentParameter.id_matpunkt 
            INNER JOIN Uppdrag u ON Matpunkt.id_uppdrag = u.ID_Uppdrag 
            INNER JOIN Företag f ON u.Ansvarigtkontor = f.ID_Företag
            WHERE MatpunktInstrumentParameter.tid_ner IS NULL
            GROUP BY f.ID_Företag, f.Namn, f.Adress, f.Postnummer, f.Postadress, f.Tele, f.Orgnummer, f.Typ, f.Logo, f.Fax, f.Mallkatalog, f.Tidszon, u.Ansvarigtkontor
            ORDER BY [Count] desc

Also I don't know if I should use AS [Count] or AS 'Count' . Or even SELECT COUNT(*) instead of what I use, OR if I even need to use an alias all together... Yeah I don't know what is best practice in sql. To be honest, I didn't write this query. It was originally in an webforms asp:SqlDataSource element. But now the whole site but this one is "upgraded" to use MVC and AngularJS. I only ask you here since my colleagues are on holiday.

And here is the mapping class:

public CompanyMap()
    {
        Table("[Företag]");
        Id(x => x.ID, "ID_Företag").Access.PascalCaseField(Prefix.Underscore);
        Map(x => x.Name, "Namn").Not.Nullable();
        Map(x => x.Address, "Adress");
        Map(x => x.ZipCode, "Postnummer");
        Map(x => x.PostAddress, "Postadress");
        Map(x => x.PhoneNumber, "Tele");
        Map(x => x.CorporateIdentityNumber, "Orgnummer");
        Map(x => x.Type, "Typ");
        Map(x => x.Logo, "Logo");
        Map(x => x.Fax, "Fax");
        References(x => x.Office, "AnsvKontor").Nullable();

        Map(x => x.TemplateFolder, "Mallkatalog");

        Map(x => x.TimeZone, "Tidszon").Nullable();

        Map(x => x.Count, "Count");

        HasMany<User>(x => x.Users).KeyColumn("ID_Företag");
    }

And here nicely mixed Swedish and English, but you only need to look at the row that says Map(x => x.Count, "Count"); . Edit: The reason for lines like the last one is that this class is used for several different things on the site if you're wondering why they are there and not used by me.

FYI this mapping works without that row. But then I just get null back on Count .

[
  {
    "id": 1,
    "name": "dummytext - Stockholm",
    "address": "dummytext 34",
    "zipCode": "123 45",
    "postalAddress": "Stockholm",
    "phone": "123456789",
    "corporateIdentityNumber": "123456-789",
    "count": null
  },

Yeah I don't want to give you the real data... I think you'll understand. And since I'm bad at NHibernate and I'm just adding stuff to a very big solution I don't know if I need to add this row here:

public static void Create()
    {
        Mapper.CreateMap<Company, CompanyViewModel>()
            .ForMember(vm => vm.PostalAddress, cfg => cfg.MapFrom(c => c.PostAddress))
            .ForMember(vm => vm.Phone, cfg => cfg.MapFrom(c => c.PhoneNumber))
            .ForMember(vm => vm.Count, cfg => cfg.MapFrom(c => c.Count));
    }
}

Finally the exception:

Invalid column name 'Count'.

Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code. 

Exception Details: System.Data.SqlClient.SqlException: Invalid column name 'Count'.

And stacktrace:

希望您可以将此图像打开更大的尺寸。

And as a last thing I want to say, if you ask me complex things about NHibernate I may not be able to answer you, like "Why aren't you doing this instead, bla bla?". I can't answer that obviously for reasons stated above.

Thank you for your time in advance for reading this long post!

Create a query with HQL or QueryOver. The query is based on your classes, not tables, and there is some information missing. I just used my fantasy to fill the gaps. There is a plain rewrite of your query in HQL, assuming some properties in your class model:

    SELECT count(Matpunkt.id) AS `Count`, 
        f.ID_Företag,
        f.Namn,
        f.Adress,
        f.Postnummer,
        f.Postadress,
        f.Tele,
        f.Orgnummer,
        f.Typ,
        f.Logo,
        f.Fax,
        f.Mallkatalog,
        f.Tidszon,
        u.Ansvarigtkontor AS `AnsvKontor`
    FROM Matpunkt m
        join m.InstrumentParameter ip
        join m.Uppdrag u
        join u.Företag f
    WHERE ip.Ner IS NULL
    GROUP BY 
        f.ID_Företag, 
        f.Namn, 
        f.Adress, 
        f.Postnummer, 
        f.Postadress, 
        f.Tele, 
        f.Orgnummer, 
        f.Typ, 
        f.Logo, 
        f.Fax, 
        f.Mallkatalog, 
        f.Tidszon, 
        u.Ansvarigtkontor
    ORDER BY `Count` desc

You get an object[] back, which is not very nice when working with an ORM.

Frankly I guess it can be simplified a lot. If I had your class model, I probably could come up with a much better solution. What actually do you want to count, from point of view of a Företag, which seems to be the central part here?

You should also consider the pure object oriented approach, where you get fully initialized objects to the memory and do some processing there (only do this with a few records).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM