Jump to content
Sign in to follow this  
wilsontc

.NET: "An object reference is required for the non-static field, method or property..."

Recommended Posts

Hi guys,

 

I have two public classes. I am trying to call a static method from one of the public classes, and am getting "An object reference is required for the non-static field, method or property <methodName>" when I try to build.

 

Class with static method:

public class Sku
	{
	/* Snip various getters and setters */

	public static IEnumerable<Sku> FindByDynamic(string searchTerm)
		{
			OrderManagerEntities db = new OrderManagerEntities();
			string escapedTerm = searchTerm.Replace("'", "''");
			return (from s in db.Skus
					where s.manufacturer_code.Contains(escapedTerm) ||
						  s.name.Contains(escapedTerm) ||
						  s.vendor_code.Contains(escapedTerm) ||
						  s.description.Contains(escapedTerm)
					select s).ToList();
		}
	}
}

I'm trying to call the above method like this:

1		public ActionResult Results(string query)
2	   {
3		   IEnumerable<Sku> skus = Sku.FindByDynamic(query);
4			return View(skus);
5		}

I'm getting the error on line 3. I thought that by performing the Linq query within the static method the I could call FindByDynamic() like this, but clearly I can't.

 

As an aside, is there a better way to query my DB? Is there a built-in method to escape my query string? I'm quite worried about it!

Share this post


Link to post
Share on other sites

is it possible one of the fields in the sku table is nullable and has a null value. EG if you call .Contains on s.description and description is null, you'll get that error.

 

probably should be disposing that OrderManageEntities instance when ur done with it too. If you did and it's causing you dramas, you probably suffer from reading microsoft documentation and this blog post may help : http://www.robertgray.net.au/2011/1/29/lin...rk-pattern.aspx <-- applies equally to EF and Linq to Sql.

Share this post


Link to post
Share on other sites

I'm guessing kikz is right. Aside from the fact that he always is, 'An object reference is required for the non-static...' is basically saying you are trying to reference a sub element of a null object, and it's not a static or const, so I've got nothin', man. So one of those calls to 'Contains' is gonna be from a null object.

 

Maybe this is showing my ignorance; but I've never gotten in to LINQ; looks like syntactic sugar and nothing more to me, (although another part of me says, heck, plenty of stuff is essentially just a nicety that could be achieved in a more manual sense).

 

On the subject of how you should be doing it...

 

[rant]

Way back in .NET 2.0 my ex-business partner, (but still best friend), and I spent a great deal of time creating generic database classes. We were youngish and naive and spent a lot of time and effort on it for a generic and customizable POS system, (that's point of sale mind you), for two beauty salons, (who years later still use it though).

 

Basically, we created generic SQL classes, generic database implementations, (we got as far as FirebirdSQL and MSSQL 05), create and update table mechanisms for program updates, (having all sorts of fields as standard to allow for historical representation etc.), and attribute types.

 

Basically then, our object classes looked a bit like this:

 

[DBTable("Payment")]
	public class Payment : DBRow
	{
		[DBField("Invoice_Id")]
		public int? InvoiceId;

We could call the database singleton to return rows like this:

 

return Database.RowList<Appointment>("client_id", client.Id);

Or to return all:

 

return Database.RowList<Client>();

We also had different SQL classes that could be used in tandem etc. and thrown at the database, (select, update, where, etc.), or straight SQL.

 

This probably doesn't do it justice; but we thought it was pretty neat. Pity the beauticians didn't appreciate the source code, (but we appreciated going on site, so it evened out). Heck, we spent about a month building a DIY reporting module that was never used, ever.

 

I could probably rustle up the code if someone really wanted it though.

 

I don't think we ever really considered threading back then, which is kinda dumb; but hey, you build what you know I guess. These days I kill for control extensions, (if I have to work with 2.0 I get by anyway).

 

It worked pretty well really, but we never really got off the ground. Now he works in a mail house sending you Telstra invoices/junk, and I work in Medical software, (primarily billing, so don't worry too much, but thank me when you get your rebate via MCOL/Easyclaim or claim through ECLIPSE).

[/rant]

Edited by Periander

Share this post


Link to post
Share on other sites

Maybe this is showing my ignorance; but I've never gotten in to LINQ; looks like syntactic sugar and nothing more to me, (although another part of me says, heck, plenty of stuff is essentially just a nicety that could be achieved in a more manual sense).

It is syntactic sugar, but it's also pretty cool. Also allows delayed execution. so whats happening with something like

var query = from s in db.Skus
				  where s.manufacturer_code.Contains(escapedTerm) ||
						  s.name.Contains(escapedTerm) ||
						  s.vendor_code.Contains(escapedTerm) ||
						  s.description.Contains(escapedTerm)
				   select s;
is a function is being create that will, when called, retrieve the appropriate data from the db.

 

it's not until it's convert into a List (ToList()) or iterated over, that database communication occurs. eg you can do a bunch of stuff but nothing will go the db until

foreach (var sku in query)
{
  // do something with each sku
}

heheh. I hate it that non-technical ppl can't see my awesome source (haha awesome source is awesome sauce lololol) and be as impressed as I was when I wrote it :D

Edited by kikz

Share this post


Link to post
Share on other sites

Thanks for the responses Kikz and Periander.

 

So then...what would I need to do to make the above work? Basically, I'm trying to keep all the "find Sku" code in the Sku class. It seems like if I moved this to the controller, it would work fine! Not what I'm after :| (Yes, this is .NET MVC 3 as you seem to have gathered)

 

Or do I need to implement Periander's "rant" pattern? ;)

Share this post


Link to post
Share on other sites

Is the SKU class a partial class, with the other parts auto generated? probably doesn't matter....

 

Anyway, you just need to test for NULL before you do a Contains.

Share this post


Link to post
Share on other sites

Is the SKU class a partial class, with the other parts auto generated? probably doesn't matter....

 

Anyway, you just need to test for NULL before you do a Contains.

SKU is not a partial class.

 

What should I test for NULL? searchTerm will always be present, and escapedTerm shouldn't ever return NULL...?

 

Sorry, I'm not sure what you mean Kikz!

 

Is there a better way of accomplishing what I want to do? Should I employ a more sophisticated method of escaping the search query string?

Share this post


Link to post
Share on other sites

so you need a gaurd clause and the following...

public class Sku
	{
	/* Snip various getters and setters */

	public static IEnumerable<Sku> FindByDynamic(string searchTerm)
		{
			// Gaurd clause		
			if (string.IsNullOrEmpty(searchTerm)) return new List<Sku>();
		
			OrderManagerEntities db = new OrderManagerEntities();
			string escapedTerm = searchTerm.Replace("'", "''");			
			return (from s in db.Skus
					where (!string.IsNullOrEmpty(s.manufacturer_code) || s.manufacturer_code.Contains(escapedTerm)) ||
						  (!string.IsNullOrEmpty(s.name) || s.name.Contains(escapedTerm)) ||
						  (!string.IsNullOrEmpty(s.vendor_code) || s.vendor_code.Contains(escapedTerm)) ||
						  (!string.IsNullOrEmpty(s.description) || s.description.Contains(escapedTerm))
					select s).ToList();						
		}
	}
}

this is based on the logical operation implication. Implication is an "If p Then q" statement. The logical equivalent of "If p then q" is "not p or q". confused? check out the truth tables for both statements :)

 

p is s.Description == null (or equivalent property of s), q is s.Description.Contains(escapedTerm)

Share this post


Link to post
Share on other sites

Thanks Kikz! Implementing the guards did the trick.

 

Seems like I have a few things to learn about the logical operators in .NET.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

×