Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Locked thread
Dietrich
Sep 11, 2001

I'm trying to learn nHibernate to replace a home grown data access layer who's developer has left the company.

This is really, really confusing. Even the getting started examples are hard to follow because they try to throw about a million new concepts at you at once.

Any sage advice for picking this up?

Adbot
ADBOT LOVES YOU

Dietrich
Sep 11, 2001

Begby posted:

Have you considered learning it in Java first? There is a lot more documentation available for that. After you learn the theory applying it to .NET shouldn't be that difficult.

I'd have to learn Java before learning it in Java, which doesn't seem like it'd be a big upgrade.

Kekekela posted:

Most .NET DAL's are not ORM-based and are very stored proc heavy, which makes switching to nHibernate a pretty big conceptual switch unless you're going to try to use it to fit the old DAL pattern which I don't think is a good idea. I'd suggest reading up on the ORM pattern of data access if you aren't familiar with it already and making sure this is the way you want to go. Fowler's Patterns of Enterprise Application Architecture has a good section on this, and I think the nHib docs probably do as well (or at least the Hib docs would), or just go to wikipedia.

The DAL we're working with now is built on a program that reads a datatable and spits out a custom .net class that can read/write data to and from it, but it has no understanding of relationships and has poor performance. It also makes absolutely no use of generics where generics make sense, such as for returning a collection of the rows from a table as a list or dictionary, instead having it's own collection and keyed collection classes with massive overhead. And the save routine updates the entire row regardless of what's actually changed. There are a million things wrong with it and I've been trying to fix them, but it seems stupid when there are open source alternatives that can do the same thing with better performance.

ray2k posted:

Never used it professionally but I've toyed with it a bit. I found Steve Bohlen's Summer of NHibernate really useful. There's also some quick tutorials on Dimecasts, and recently Ayende has blogged about the multitude of mapping options.

Thank you, I'm gonna look into these.

Dietrich
Sep 11, 2001

You could do that with a control that contains a repeater quite easily, or with a asp:table if you prefer.

Dietrich
Sep 11, 2001

Am I missing something?

I'm using NHibernate and thus I've got an object that has a ISet of another object in it.

I was under the impression that ISet would prevent me from adding the same other object twice, as long as I had a working equals on the other object- but equals never gets called and I'm able to add multiple other objects no problem. I'm using the HashedSet implementation from Iesi.Collections- so I'm guessing that I need to implement GetHash on my objects in order for it to properly identify that an other object is in the set.

Is there an easier strategy for this problem? I don't want to have to go around implementing gethash and equals on all my custom objects.

Dietrich
Sep 11, 2001

shrughes posted:

When you override Equals, you must override GetHashCode in a consistent manner. This is not supposed to be hard.

Yeah I just did some reading for other examples of people implementing GetHashCode and i realized how easy it can be. The first few examples I saw were all kinds of complicated.

Dietrich
Sep 11, 2001

nhibernate requires virtual events and those don't exist in vb.net

why didn't anyone warn me oh god?

Now I have to teach myself c#. I've been meaning to switch for a while now, so woohoo.

Dietrich
Sep 11, 2001

shrughes posted:

Pardon my ignorance; what is a virtual event?

an event that can be overridden by an inheriting object.

Dietrich
Sep 11, 2001

Nurbs posted:

In order to properly get the answers I want while iterating through the Collection<QuestionBase> I would need to cast the given object in order to retrieve it's Answer value. Or, I figure out a way for the QuestionText and QuestionBoolean child objects (TextBox and CheckBox) to feed their values into the Answer property

Why do you have to cast them?

foreach(QuestionBase QB in yourContainerObject)
theAnswer = QB.Answer

should work fine, as long as they override the answer property of the base class.

Dietrich
Sep 11, 2001

After 4 days of using C# the only thing I miss about VB.net is the My namespace. Remind me again why C# doesn't have that?

Dietrich
Sep 11, 2001

biznatchio posted:

It does, kinda.

Yeah I saw that but the parts of My that I used most often where under My.User, My.Application, My.Settings, ect, none of which are covered there... :(

Dietrich
Sep 11, 2001

How do I check if an NHibernate collection object is a lazy loading proxy or a fully loaded object?

I have some code I want to run on a classes child after this class's children are loaded, but I don't want that code to go ahead and load the children. Unfortunately the code needs to access the parent item's children collection to get some siblings of each child, which leads to a "illegal access exception" until lazy loading is complete.

What I'm looking for is a way to test if a collection has been loaded.

Edit: Asked Steve Bohlen on Twitter- NHibernateUtil.IsPropertyInitialized

Dietrich fucked around with this message at 20:55 on May 12, 2009

Dietrich
Sep 11, 2001

This is freaking driving me insane, so I'm cross posting this from Stack Overflow.

I'm trying to to setup Memcached 2nd level caching with NHibernate. I've followed what documentation I could find, including downloading the project from SVN and looking at how it is configured in their test project, and ended up with this in my app.config.

code:
   <configuration>
      <configSections>
        <section name="memcache" type="NHibernate.Caches.MemCache.MemCacheSectionHandler,NHibernate.Caches.MemCache" />
      </configSections>
      <memcache>    
        <memcached host="xx.xx.xx.xx" port="11211" weight="10" />
      </memcache>
    </configuration>
However, when the MemCache provider code in `NHibernate.Caches.MemCache` calls `configurationmanager.getsection("memcache")`, null is returned, which causes it to error out.

I have three projects, .UI, .Core, and .Data - the app.config is for .UI and .Data is where `SessionFactory` gets built and the code that wants to load this configuration section is launched. .Data has the `Nhibernate.Caches.Memcache` reference, and I've tried adding it to .UI, however that did not solve the issue.

What is incorrect about this configuration? Or perhaps is it something about my project? Does anyone have any experience at all with `NHibernate.Caches.MemCache`? There is not much information about it to be found via Google.

Dietrich
Sep 11, 2001

Why don't you add some events to the child form and have the parent handle those? That's how I typically do it, it makes the child form more reusable.

Dietrich
Sep 11, 2001

uXs posted:

And that just works a lot better. DataSets are cumbersome to use and really awkward to maintain. I've made a few apps with them, and I didn't like it. Ripping them out and using plain objects instead is much nicer.

The only place where I do still use datasets out of free will is reporting. Stitch together an sql query, create a datatable out of it, bind it to almost any kind of grid, and you're done. You can bind collections of objects as well, but I think datasets are more flexible because you can easily throw stuff together without having to define it beforehand. (Maybe there's an alternative with anonymous classes, but I haven't tried that.)

I created a data-table proxy generic class that takes a collection<T> and a collection<string> of properties you want to be columns in your data table and spits out a system.data.datatable with a row for each object in the collection. It uses reflection to find the method info for the properties by name and then caches the method info, so it's not too bad on the old performance front. Datatables are what reporting loves.

Dietrich
Sep 11, 2001

Anyone messed with Code-Name Velocity yet?

Dietrich
Sep 11, 2001

I have just invented a generic class that will take an List of anything and output a data table containing whatever the hell you want from that list. You define the desired columns by building a Dictionary<string, Func<T, object>>, which means it takes lambda expressions.

I'm posting this for two reasons.

1- It's freaking awesome and I think you guys will like it.
2- I would like to make it faster and was hoping for some suggestions.

code:
public class DataTableProxy<T>
    {
        public static DataTable GetTable
        (
           List<T> FromList, 
           Dictionary<string, Func<T, object>> Columns
        )
        {
            var DT = new DataTable();
            int MaxColumnIndex = Columns.Count - 1;
            var UnusedColumns = new List<string>();
            
            var e = Columns.GetEnumerator();
            while (e.MoveNext())
            {
                DT.Columns.Add(e.Current.Key);
                UnusedColumns.Add(e.Current.Key);
            }
            
            
            foreach (T Item in FromList)
            {
                object[] values = new object[Columns.Count];
                e = Columns.GetEnumerator();
                int x = 0;
                while (e.MoveNext())
                {
                    object returnV = e.Current.Value.Invoke(Item);
                    values[x++] = returnV;
                    if (returnV != null && UnusedColumns.Contains(e.Current.Key))
                        UnusedColumns.Remove(e.Current.Key);                    
                }
                DT.Rows.Add(values);
            }

            foreach (string s in UnusedColumns)
                DT.Columns.Remove(s);

            return DT;
        }
     }
and here's an example of me using it.

code:
var Columns = new Dictionary<string, Func<DaylogTest, object>>();
Columns.Add("Sample", dlt => dlt.Daylog.Sample.SampleName());
Columns.Add("Date", dlt => dlt.TestDate.HasValue ? dlt.TestDate.Value.ToShortDateString() : string.Empty);
Columns.Add("Entered By", dlt => dlt.EnteredBy == null ? string.Empty : dlt.EnteredBy.LastCommaFirst());            
datagrid1.datasource = DataTableProxy<DaylogTest>.GetTable(listdlt, Columns);

Dietrich
Sep 11, 2001

Ah thanks, that was some leavings from my last implementation when I was using a custom key-value pair class and addressed the columns collection via index.

Dietrich
Sep 11, 2001

dwazegek posted:

Why are you iterating through columns manually, and not with a foreach loop? You're also not disposing the enumerators after you're done with them.

Change unusedColumns to a HashSet<string>, calling Contains or Remove on a List is a O(n) operation, for a HashSet it's O(1).

You don't have to check to see if a List (or HashSet) contains an item before calling remove. In both cases Remove returns a boolean indicating if a matching item was found (and removed).

Change FromList from a List<T> to an IEnumerable<T>, you're only iterating through the items, so there's no reason to limit yourself to just lists.

You can call a delegate directly without using invoke, but it doesn't matter (aside from being shorter).
code:
e.Current.Value(item);
//instead of:
e.Current.Value.Invoke(Item);

I don't think you can iterate though a Dictionary<Tkey, TValue> manually. Aside from that, great stuff and I'll use the heck out of it.

Edit: but you can cast the .keys and .values collection to an array and then step though that instead, which I think would be higher performance, trying that now.

Dietrich fucked around with this message at 13:38 on Jun 30, 2009

Dietrich
Sep 11, 2001

The Noble Nobbler posted:

Not bad, but you can do this with a way smaller function and Linq. I can show you if you're interested

I'm listening.

Dietrich
Sep 11, 2001

The end result of all this poo poo is a form where the user's can pick what columns they want, and then a data table is filled with the results. The columns, in this case, are generally results of a function ran against an object with a fixed parameter (per column). Column 1 might display the result of obj.getValue(1) while column 2 might be obj.getValue(15), where 1 and 15 relate to the primary key of a table that stores all the column definitions.

The data being displayed is super-normalized, let's just put it that way. I can post the ERD if you want to gently caress your mind right out of your head.

Dietrich
Sep 11, 2001

Check out Expresso for all your RegEx creation/checking needs. It provides a nice little logic tree that really illustrates what your regex is being interpreted to mean.

Dietrich
Sep 11, 2001

Wouldn't it be better to combine the list of used TCP and UDP Ports and then step though them and return the first open pair you see that meets your needs?

code:
private static UdpClientPair GetUdpClients()
{
      const int minPort = 5000;
      const int maxPort = 65535;
      var properties = IPGlobalProperties.GetIPGlobalProperties();
      var tcpUsed = from tcp in properties.GetActiveTcpListeners()
                    where tcp.Port >= minPort && tcp.port <= maxPort
                    select tcp.Port;
      var udpUsed = from udp in properties.GetActiveUdpListeners()
                    where udp.Port >= minPort && udp.port <= maxPort
                    select udp.Port;
      var Used = tcpUsed.Concat(udpUsed).OrderBy(P => P);

      int LastOddPort = (minPort % 2 == 1) ? minPort : minPort - 1;

      foreach (int Port in Used)
      {
          if (LastOddPort < Port - 2)
              break;

          if (Port % 2 == 1)
          {
              LastOddPort = Port;
              continue;
          }              
      }

    if (LastOddPort <= maxPort - 2)
         return new UdpClientPair(LastOddPort + 1, LastOddPort + 2};

    //TODO: better exception
    throw new InvalidOperationException("Could not find valid port pair");
}
Edit: Fixed a few edge cases, like no ports used.
Edit2: god why do I keep tweaking this?!

Dietrich fucked around with this message at 13:49 on Jul 14, 2009

Dietrich
Sep 11, 2001

Now you're playing with power.

Nice.

Dietrich
Sep 11, 2001

Postsharp is your lover and your best friend when it comes to poo poo like that.

Dietrich
Sep 11, 2001

I've got a Datatable object that I would like to make a spreadsheet in a .xls file.

What is the best way to make this happen?

Dietrich
Sep 11, 2001

Earlier this year I was learning nhibernate and was pointed to the Summer of NHibernate series which was absolutely invaluable. Now I am interested in picking up WPF- is there any tutorial for this which is on par with Summer of NHibernate?

Dietrich
Sep 11, 2001

In a Winforms MDI application, how do I figure out which control on which form has focus?

Dietrich
Sep 11, 2001

I just posted my awesome data table proxy class on codeplex. I don't know how specific the need for this kind of object is, but I use it all over the freaking place along with DataGrids for easily presenting tabular data. Combined with lambda expressions you can very quickly do specific aggregations of child object collections and pretty much anything the gently caress else you want to do.

http://datatableproxy.codeplex.com/

Enjoy. Rate it if you like it.

Dietrich
Sep 11, 2001

I don't really have full understanding of either library you are using, but can filehelpers take a datatable object and convert it to a .csv file?

If so perhaps you can use my DataTableProxy thing instead of nvelocity for a no nonsense "take these objects and format an output like this" solution.

Sorry for the shameless plug.

Dietrich
Sep 11, 2001

Just to share a nice little .dll I've found, MyXls has to be the easiest to use library for creating .xls documents I've ran across. No need for excel interop libraries or code templates or reflection or any of that jazz, just a straight forward API that creates a .xls document that you can then do whatever the hell you want with.

Here is a quick and easy sub routine that uses this to create and save a .xls containing all the data from a datatable object.

code:
    Public Sub ExportDatatable(ByVal dt As DataTable)
        Dim dialog As New SaveFileDialog With {.Filter = "Excel files(*.xls)|*xls"}
        If (dialog.ShowDialog = DialogResult.OK) Then
            Dim doc As New XlsDocument With {.FileName = IO.Path.GetFileName(dialog.FileName)}            
            Dim sheet As Worksheet = doc.Workbook.Worksheets.Add("Exported")
            Dim enumColumns As IEnumerator = dt.Columns.GetEnumerator
            Dim enumRows As IEnumerator = dt.Rows.GetEnumerator

            Dim row As Integer = 1
            Dim column As Integer = 1
            Do While enumColumns.MoveNext
                Dim cell As Cell = sheet.Cells.Add(row, column, DirectCast(enumColumns.Current, DataColumn).ColumnName)
                cell.Font.Weight = FontWeight.Bold
                cell.BottomLineStyle = 1
                column += 1
            Loop

            row = 2

            Do While enumRows.MoveNext
                Dim currentRow As DataRow = DirectCast(enumRows.Current, DataRow)
                For column = 1 To dt.Columns.Count
                    Dim value As Object = currentRow(column - 1)
                    If Not TypeOf value Is DBNull Then
                        If IsNumeric(value) Then
                            sheet.Cells.Add(row, column, CDec(value))
                        Else
                            sheet.Cells.Add(row, column, value)
                        End If
                    End If
                Next
                row += 1
            Loop

        If My.Computer.FileSystem.FileExists(dialog.FileName) Then My.Computer.FileSystem.DeleteFile(dialog.FileName)
        doc.Save(IO.Path.GetDirectoryName(dialog.FileName))
        End If
    End Sub
Check it out if you're always expected to have .xls outputs from your poo poo like I am.

Dietrich
Sep 11, 2001

Ok I'm trying to teach myself xaml and WPF, and this data binding poo poo has my head spinning.

Anyone got a good tutorial or resource on getting this poo poo done? As usual MSDN's tutorials skip about a hundred steps.

Dietrich
Sep 11, 2001

Log4net- who uses this? How do I go about quickly picking up how it works? Does anyone have some pre rolled logger classes that kick rear end to use?

Dietrich
Sep 11, 2001

Make a button that does that once, then make all your buttons inherit from that button.

Dietrich
Sep 11, 2001

CRIP EATIN BREAD posted:

I'm developing an app in c#, however this one is a bit more involved than what I've done in the past with the .net framework. It's a form based application, and by default it looks like every bit of information I've seen has the creation and navigation of multiple forms handled by the forms themselves. Is this really the standard practice, or is it just because the default code generated by the project wizards tends to lean in this direction?

Sweet merciful crap do not do your application that way.

Dietrich
Sep 11, 2001

jarito posted:

Is there an accepted way to do this? I typically do web development, but I would be interested in what would be considered best practice here.

Create a singleton shell class that you can issue commands to- ie: Shell.OpenOrdersForm

That way when you get all fancy with needing to make sure a form can only be opened once or with switching forms to an active window in order to prompt it's easy to do, and you can obfuscate the various form construction methods from other forms so that you only have to change things in one place.

Dietrich
Sep 11, 2001

Var is awesome. When I change the return type of something from, say, list<t> to ienumerable<t>, IT KEEPS WORKING.

Dietrich
Sep 11, 2001

Fire Storm posted:

Here's a question I feel stupid for asking, but...

Spurred by the SA GameDev contest, I've decided to try my hand at programming again. The last time I tried programming it was on Visual Studio 2003 or 2005 about 5 years ago and trying to learn from the 2010 pro demo.

Actual question: All the tutorials that I've seen say the same thing "Select the Windows Application template." Only problem is... I don't see that template. Windows FORMS Application or WPF Application, yes, but not one simply named "Windows Application." I remember seeing one game programming tutorial saying that I don't want Windows Forms Application, so what do I do? Have the tutorials for 2010 just not updated it to say "Yeah, use forms"?

Do not use either of those, they are terrible bases for games. Download XNA.

Dietrich
Sep 11, 2001

EF is really just Linq to SQL made usable for anything more complex than a single form.

That being said, use NHibernate with Fluent mappings.

Dietrich
Sep 11, 2001

Why are your UI and your DB classes the same?

You either designed your DB around your UI's concerns or designed your UI around your DB's concerns.

Adbot
ADBOT LOVES YOU

Dietrich
Sep 11, 2001

highme posted:

Next question time, a combination of reference material written for C# and lecture slides that are a bit disjointed, has left me a bit confused on the steps to turn the list created previously into a searchable hashtable.


the Psuedo-code provided in the assignment says to define hashtables for the route and distance at the class level (distanceTab and routeTab). distanceTab has a key of NODEID as integer and a value of "distance to origin" as double. routeTab has a key of ToNode as integer and value of FromNode as integer.


I believe I've declared those properly here, however when I try to add "as integer" or "as double" after the value it gives me an "end of statement expected" error and I can't figure out why as I'm copying code from the reference.
code:

        'create hashtable for distance
        Dim distanceTab As New Hashtable()
        distanceTab("NodeID") = "Distance"

        'create hashtable for route
        Dim routeTab As New Hashtable()
        routeTab("StartNode") = "EndNode"
I've got to run my daughter to soccer practice so this is where my train of thought needs to end for now.

Basically my questions are A)did I properly declare my hashtables and B) in my "find route" button on_click event (that isn't listed yet) do I need to create a queue to pull the hashtable from, or just use the ComboFrom.SelectedItem() method from my comboboxes (named ComboFrom and ComboTo).

Do they have to be "hashtables"? Because a Dictionary<tk, tv> is pretty much what you want. Although in visual crappy syntax that would be Dictionary(of tk, tv)

  • Locked thread