Everyone knows this
using (var db = new DatabaseEntites())
{
var row = db.SomeTable.SingleOrDefault(r => r.Id == 5)
}
I planned to create a static class with a static method like this
public static class SomeTableRepository
{
public static class GetSomeTableRow(DatabaseEntities db, int id)
{
return db.SomeTable.SingleOrDefault(r => r.Id == 5);
}
}
and the first code would then look like this
using (var db = new DatabaseEntites())
{
var row = SomeTableRepository.GetSomeTableRow(db, id);
}
If this would be a web app...would that kind of programming be ok...or could that kind of programming cause some trouble?...or is this perfectly good code :)
The code is technically acceptable, but why would you do it? It's creating an indirection without making the code substantively more concise. Thus you make your code harder for most people to understand. The benefit is your code is two characters shorter. That doesn't seem like a win to me.
Myself, I would use the standard LINQ operators unless I'm genuinely adding some real value.
As Kirk said, I think the only gain is minor readability. However, if you add this in front of your first parameter and make this an extension method, then you might gain some readability for potential readers of your code:
UPDATE
I also noticed that public static class GetSomeTableRow would not compile. I changed it to be more generic and less confusing for future readers (class to YourClassName)
public static class SomeTableRepository
{
public static YourClassName GetSomeTableRow(this DatabaseEntities db, int id)
{
return db.SomeTable.SingleOrDefault(r => r.Id == 5);
}
}
...
database.GetSomeTableRow(id);
Furthermore, you could rename this to make it read more like what it actually is:
database.GetOneRowFromSomeTableById(id);
Yes, it is lengthy, but the only reason to abstract such a simple method as SingleOrDefault would be to make the code even readable at a glance. The ById part is debatable since the parameter is named id (and it makes it seem redundant), however that only shows up while coding with intellisense. You could leave it out (or take it down to just By without Id...but that leaves too much for each implementer IMO)
database.GetOneRowFromSomeTable(id);
Related
consider the following scenario:
public class DBEntry {
public string Id;
}
public class ComputedEntry {
public string Id;
public int ComputedIndex;
}
IQueryable<DBEntry> databaseQueryable; // Somewhere hidden behind the API
IQueryable<ComputedEntry> entryQueryable; // Usable with the API
Let's assume each DBEntry has a unique Id and not much else. A ComputedEntry has a 1:n relationship with DBEntry, meaning that a DBEntrycan be expanded into more than a single ComputedEntryduring execution of the query.
Now, I am trying to query entryQueryable to get a range of computed indices, e.g:
entryQueryable.Where(dto => dto.ComputedIndex < 10 && dto.Id == "some-id");
What I'm looking for is a way of separating the given query expression to only push down the relevant parts of the query to the databaseQueryable. In the example above something like this should happen (probably in the implementation of IQueryableProvider.Execute when using the entryQueryable):
var results = databaseQueryable.Where(e => e.Id == "some-id").ToList();
int i = 0;
return results.Select(e => new ComputedEntry(e.Id, i++));
So basically I'd like the query to be separated and the relevant/compatible parts should be pushed down to the databaseQueryable.
The obvious question would be: How should I approach this? I tried to figure out a way of separating the expression with an ExpressionVisitor, but haven't been very successful here and it seems like this is a rather complex task.
Any ideas? Maybe there is an already existing method of optimizing/translating the query I am not aware of? I have looked through the documentation but couldn't find anything useful here.
Many thanks for your suggestions!
The question is theoretical and I want to understand general difference and performance matter in particular between 2 different definition that give the same result.
I have a class GLProcessingModel that has a reference to a graph (So it has not direct references to the UI). The class has a method that determine of an item has some value (currently my code looks like that):
private bool IsEmployerSuperWorkCover(MPCurrentPayPayItem payItem)
{
return PXSelectJoin<MPPayItem,
InnerJoin<MPPayItemType, On<MPPayItemType.payItemTypeID, Equal<MPPayItem.payItemTypeID>>,
InnerJoin<MPRollupItem, On<MPRollupItem.payItemID, Equal<MPPayItem.payItemID>>,
InnerJoin<MPRollup, On<MPRollup.rollupID, Equal<MPRollupItem.rollupID>>>>>,
Where<MPRollup.name, Equal<Required<MPRollup.name>>,
And<MPRollupItem.payItemID, Equal<Required<MPRollupItem.payItemID>>,
And<MPPayItemType.payItemTypeCD, Equal<Required<MPPayItemType.payItemTypeCD>>>>>>
.Select(Graph, MPPayItem.WORCOVER_AU, payItem.PayItemID, MPPayItemType.EMPLOYER_SUPER)
.AsEnumerable()
.Any();
}
What is the difference if I define the same expression in the different way (or something like that):
PXSelectJoin<MPPayItem, InnerJoin<MPPayItemType, On<MPPayItemType.payItemTypeID, Equal<MPPayItem.payItemTypeID>>,
InnerJoin<MPRollupItem, On<MPRollupItem.payItemID, Equal<MPPayItem.payItemID>>,
InnerJoin<MPRollup, On<MPRollup.rollupID, Equal<MPRollupItem.rollupID>>>>>,
Where<MPRollup.name, Equal<Required<MPRollup.name>>,
And<MPRollupItem.payItemID, Equal<Required<MPRollupItem.payItemID>>,
And<MPPayItemType.payItemTypeCD, Equal<Required<MPPayItemType.payItemTypeCD>>>>>> EmployerSuperWorkCoverQuery;
private bool IsEmployerSuperWorkCover(MPCurrentPayPayItem payItem)
{
if (EmployerSuperWorkCoverQuery == null)
{
EmployerSuperWorkCoverQuery = new PXSelectJoin<MPPayItem, InnerJoin<MPPayItemType, On<MPPayItemType.payItemTypeID, Equal<MPPayItem.payItemTypeID>>,
InnerJoin<MPRollupItem, On<MPRollupItem.payItemID, Equal<MPPayItem.payItemID>>,
InnerJoin<MPRollup, On<MPRollup.rollupID, Equal<MPRollupItem.rollupID>>>>>,
Where<MPRollup.name, Equal<Required<MPRollup.name>>,
And<MPRollupItem.payItemID, Equal<Required<MPRollupItem.payItemID>>,
And<MPPayItemType.payItemTypeCD, Equal<Required<MPPayItemType.payItemTypeCD>>>>>>(Graph);
}
return EmployerSuperWorkCoverQuery.Select(MPPayItem.WORCOVER_AU, payItem.PayItemID, MPPayItemType.EMPLOYER_SUPER)
.AsEnumerable()
.Any();
}
I believe every-time when graph calls the method in the class GLProcessingModel, EmployerSuperWorkCoverQuery will be null and needs to initialize it.
I believe there is better option to define the same behavior. return PXSelectJoin<MPPayItem, ... looks like db connection, sql generation etc and not the best option.
How it changes the caching mechanism?
What is optimal way to implement such behavior with the best performance?
Creating a C# object (dataview) will not significantly impact performance.
There are only two approaches which will yield measurable differences:
Use the low level PXDatabase class for data access instead of
PXSelect.
Use the Prefetch pattern to cache the results.
Reference: https://www.acumatica.com/blog/application-wide-caching-with-slots-and-iprefetchable/
I tried my best to explain in the title, however I am trying to achieve giving linq statements an 'alias' and still use them in dot notation. Allow me to explain further.
below we have a list that has a linq statement applied:
private List<string> _matches;
var output = _matches.Where(x => x.EntityScore == 100).ToList();
I agree that this is simple to read. However I wish to simplify it further especially when the statements start to get bigger. This is an example of linq getting longer than I care for:
private List<string> _matches;
var matchAddressList = _matches.Where(x => x.EntityDetails.Addresses.Any(x => x.Street.Equals(inputObject.Address)
&& x.StateProvinceDistrict.Equals(inputObject.State)
&& x.City.Equals(inputObject.City))).ToList();
What I am trying to do is alias certain groups of LINQ and then call that linq as a dot operator
for example:
var finalOutput = _matches.perfectMatches().addressMatches(inputObject).someOtherMatchCondition(inputObject)
I think the above line is clear and easily readable. Future devs dont necessarily have to look into the logic. They can read the business domain name and understand what it does.
I want to avoid the following line, as I believe the previous code is more clean:
var finalOutput = someOtherMatchCondition(addressMatches(perfectMatches(_matches)));
the previous line is how I feel you would go about it using functions at a basic level. However I am struggling to find a way to create an alias or encapsulate the linq logic into a business domain name and then use that as a dot operator.
I have tried expression body definitions:
public List<string> perfectMatches => _matches.Where(x => x.EntityScore == 100).ToList();
is this going to require extensions of another class? or the writing of generics? or am I perhaps unaware of a standard way of doing this?
Update: maybe this is helpfull too:
How to add custom methods for LINQ queries (C#)
It has to be an extension method to make use of the dot notation.
Do you mean something like that. It is rather pseudo code than working. You may have to play around with the types or try out some kind of generic approach:
public class ProductionCode
{
public void MyMain()
{
var myList = new List<EntityThingType>() { .... };
var newList = myList.PerfectMatches().AddressMatches(myInputObject).ToList();
}
}
public static class test
{
public static IEnumerable<EntityThingType> PerfectMatches(this IEnumerable<EntityThingType> myList)
{
return myList.Where(x => x.EntityScore == 100);
}
public static IEnumerable<EntityThingType> AddressMatches(this IEnumerable<EntityThingType> myList, MyObjectType inputObject)
{
return myList.Where(x => x.EntityDetails.Addresses.Any(x => x.Street.Equals(inputObject.Address)
&& x.StateProvinceDistrict.Equals(inputObject.State)
&& x.City.Equals(inputObject.City)));
}
}
I think what you are looking for is Extension Methods. You can have the perfectMatches() method be an extension method that takes an IEnumerable<string> and return the same. Then you can chain those together.
I know the "logical approach" to this question ...
This is logically correct:
public static Department FindDepartment(Employee emp)
{
if(emp.ID > 500)
{
return new Department("Department for Over 500");
}else{
return new Department("Department for 500 and under");
}
}
... because the Department is really based off the Employee, whereas the following is logically incorrect:
public static int GetPlusOne(Employee emp)
{
return emp.ID + 1;
}
... because the method really isn't a function of an Employee ... it's just an integer modifier.
That all said (and feel free to point out if I'm in error on that for some reason), Is there any performance lost when passing the entire instance of Employee?
I have an underlying method that will be called most of the time from within a different class and so I'm trying to weigh performance vs. logical here. But if there's nothing to be worried about performance-wise then the choice becomes logical (haha ... punny).
In terms of the method call itself, any performance loss will not be enough to matter. More important is the effect this has on your program's maintainability.
If you take an Employee as an argument, someone must always ensure that they have en Employee before they can call your method. On the one hand, this helps to avoid mistakes where people pass the wrong int variable into your method:
int plusOne = GetPlusOne(emp.DirectReportId); // oops, didn't you mean EmployeeId?
On the other hand, it can be annoying if all I have is the employee's ID, and now I have to do some kind of database access to produce an actual Employee object out of it.
foreach(var pinkSlip in pinkSlips)
{
var employee = GetEmployee(pinkSlip.EmployeeId); // ugh, is this really necessary?
int plusOne = GetPlusOne(employee);
...
}
If GetEmployee does something expensive like a database roundtrip, the above code could potentially be very slow: not because of the call to GetPlusOne, but because you have to produce an Employee when all you're interested in is the ID.
Ultimately, you'll have to make this decision based on how you expect the method in question to be used.
IF Employee is a class then .NET passes a reference (which is basically a pointer) and NOT the instance itself... so performance is rather similar to a real instance method (which too receives a reference to the instance as an implicit parameter called this).
You can even define them as Extension Methods like:
public static Department FindDepartment(this Employee emp)
{
if(emp.ID > 500)
{
return new Department("Department for Over 500");
}else{
return new Department("Department for 500 and under");
}
}
then you call it like any instance method on an instance of Employee:
Employee emp = ...;
Department dep = emp.FindDepartment();
i would actually do both, depFindBy(int employeeId) and depFindBy(Employee employee). not much work and it can be convenient to have both methods later.
I have the following code I am trying to consolidate. (here are two examples) but with this repeated pattern of checking if fields are null then if they are different and if yes, then setting the new value into the old value.
What is the best way to rewrite this to avoid duplication?
if (String.IsNullOrEmpty(f.FirstName))
{
if (exisingPerson.FirstName != f.FirstName)
{
change = true;
exisingPerson.FirstName = f.FirstName;
}
}
if (String.IsNullOrEmpty(f.LastName))
{
if (exisingPerson.LastName != f.LastName)
{
change = true;
exisingPerson.LastName = f.LastName;
}
}
I don't think you can do much to remove the duplication (at least not without introducing reflection which will probably just muddy the code rather than make it clearer).
However you could look at implementing INotifyPropertyChanged which is a standard pattern for notifying about changes to an object instead of the boolean you are currently using:
How to: Implement the INotifyPropertyChanged Interface
If you look at the example code there it also has a certain amount of repetition.
You can use delegates:
public static bool ChangeProperty(Func<Person, string> getter, Action<Person, string> setter, Person person, string value)
{
if (!String.IsNullOrEmpty(value) && !getter(person).Equals(value))
{
setter(person, value);
return true;
}
return false;
}
and call it with lambdas like this:
var barneyRubble = new Person();
change = ChangeProperty(p => p.FirstName, (p, v) => p.FirstName = v, barneyRubble, "Fred");
An even better thing to do would be to put the method in the Person class and eliminate that third parameter altogether, replacing it with this.
Probably overkill, but if you're making a lot of these kind of property changes it might be valuable, and I think it's an interesting pattern anyway.
For just a couple of fields, your code may be the best. Short and simple.
If you're doing this a lot, you could use reflection to iterate through each field in the object, and perform the operation if it's a String.
However, the downside of this is readability. Perhaps you're better off being explicit, and protecting against typos through copy/paste through extensive use of unit tests.