In a graph model I have a vertex called timeCategory with childs year-vertices, month-vertices and day-vertices. I am able to identify a year with the edge-label with IS_YEAR, a month with IS_MONTH, etc.
I want to do a query that returns all vertices of a given year range similarly to the following code:
GremlinPipeline yearPipe = new GremlinPipeline(timeCategory).out("IS_YEAR").property("year")
.filter(new PipeFunction<Integer, Boolean>() {
public Boolean compute(Integer i)
{
return i < 2013 && i >= 2011;
}
});
for(Object v : yearPipe) {
//v is an Integer, but i need the vertex
System.out.println(v);
}
... this works great for printing all property-values (the years as integers), but what I need is a list of all VERTICES which year-properties are between a given range.
My second question is about making a intersection from values in pipes.
For example: I have three pipes, a yearpipe, a monthpipe, and daypipe, and the pipes containg vertices that identifies a year, month, or day.
Is it possible to get all outgoing vertices to one special date...
Semi-Code: allVertices2012-01-01 = yearpipe.out() AND monthpipe.out() AND daypipe.out
sure, i can do some compares in some for-each-loops, but i wanted to know if there is a (simple) gremlin - way to do it better.
There are two solutions to your problem. Here it is in Gremlin-Groovy:
timeCategory.out('IS_YEAR').filter{year = it.getProperty('year'); year < 2013 && year >= 2011}
-OR-
timeCategory.out('IS_YEAR').property('year').filter{it < 2013 && it >= 2011}.back(1)
Here is your answer in Gremlin-Java code (for the second representation above):
GremlinPipeline yearPipe = new GremlinPipeline(timeCategory).out("IS_YEAR").property("year")
.filter(new PipeFunction<Integer, Boolean>() {
public Boolean compute(Integer i)
{
if(i<2013 && i>=2011)
return true;
else
return false;
}
}).back(1);
Okay after some short-tutorials reading, I figuered out that the param on .back(x) should be 2... so, with .back(2) you will get your vertices.
btw. the examples provided at http://markorodriguez.com are much better for a gremlin quick start then these on github-wiki, in my opinion.
To my second question: I found out there is a topic on gremling-users, that describes pretty well my problem:
http://groups.google.com/group/gremlin-users/browse_thread/thread/d245b1a25ac1fac8/514931b1e3bf9e30?lnk=gst&q=intersect#514931b1e3bf9e30
Related
I want to rename a connector after a shape has been dropped.
Lets say I have a shape1 and I dropped a shape2 connected with shape1.
I want the connector shape between shape1 and shape2 so that I can rename it.
I guess it depends on what stage you intercept the drop. If it's immediately, you might make some assumptions about how many connectors might be involved, but if if some time after the drop then you might want to determine how many connections are involved.
As an example, with the following shapes:
...you could approach this in a number of ways:
Use the GluedShapes method working back from ShapeTwo
Use the GluedShapes method including the 'from' shape
Iterate through the Connects collection of the Page
Iterate over the Connect objects in on your target shape (ShapeOne)
I would definitely try and use the GluedShapes method (which came into Visio in 2010) over the Connect objects, but I'm adding them here as they can be useful depending on what you're trying to achieve.
Here's an example using LINQPad:
void Main()
{
var vApp = MyExtensions.GetRunningVisio();
var vPag = vApp.ActivePage;
//For demo purposes I'm assuming the following shape IDs
//but in reality you'd get a reference by other methods
//such as Window.Selection, Page index or ID
var shpOne = vPag.Shapes.ItemFromID[1];
var shpTwo = vPag.Shapes.ItemFromID[2];
Array gluedIds;
Console.WriteLine("1) using GluedShapes with the 'to' shape only");
gluedIds = shpTwo.GluedShapes(Visio.VisGluedShapesFlags.visGluedShapesIncoming1D,"");
IterateByIds(vPag, gluedIds);
Console.WriteLine("\n2) using GluedShapes with the 'to' and 'from' shapes");
gluedIds = shpTwo.GluedShapes(Visio.VisGluedShapesFlags.visGluedShapesIncoming1D, "", shpOne);
IterateByIds(vPag, gluedIds);
Console.WriteLine("\n3) using the Connects collection on Page");
var pageConns = from c in vPag.Connects.Cast<Visio.Connect>()
where c.FromSheet.OneD != 0
group c by c.FromSheet into connectPair
where connectPair.Any(p => p.ToSheet.ID == shpOne.ID) && connectPair.Any(p => p.ToSheet.ID == shpTwo.ID)
select connectPair.Key.Text;
pageConns.Dump();
Console.WriteLine("\n4) using FromConnects and Linq to navigate from shpOne to shpTwo finding the connector in the middle");
var shpConns = from c in shpOne.FromConnects.Cast<Visio.Connect>()
where c.FromSheet.OneD != 0
let targetConnector = c.FromSheet
from c2 in targetConnector.Connects.Cast<Visio.Connect>()
where c2.ToSheet.Equals(shpTwo)
select targetConnector.Text;
shpConns.Dump();
}
private void IterateByIds(Visio.Page hostPage, Array shpIds)
{
if (shpIds.Length > 0)
{
for (int i = 0; i < shpIds.Length; i++)
{
//Report on the shape text (or change it as required)
Console.WriteLine(hostPage.Shapes.ItemFromID[(int)shpIds.GetValue(i)].Text);
}
}
}
Running the above will result in this output:
It's worth bearing in mind that the Connects code (3 and 4) makes the assumption that connector shape (1D) are being connected to the flowchart shapes (2D) and not the other way round (which is possible).
You can think of the connect objects as being analgous to connection points, so in the diagram, the three connector shapes generate six connect objects:
Anyway, hope that gets you unstuck.
UPDATE - Just to be clear (and to answer the original question properly), the code to get all outgoing connectors from ShapeOne would be:
Console.WriteLine("using GluedShapes to report outgoing connectors");
gluedIds = shpOne.GluedShapes(Visio.VisGluedShapesFlags.visGluedShapesOutgoing1D, "");
IterateByIds(vPag, gluedIds);
I fail to translate a sql query to a linq query that could calculate some stock.
This is my test query that I'm trying to convert to a linq query.
SELECT
i.*,
(SELECT COUNT(t.*) FROM tickets t
WHERE t.starttime::time = i.sessionstarttime::time
AND t.starttime::date = '2018-04-06'::date)
as stock
FROM items I
-- note that the hardcoded date ('2018-04-06') is a function parameter
( tl;dr; how would you convert this PostgreSQL query to LINQ? )
My attempts so far are the variations of the following query:
var items = await _context.Items.Select(x => new Item
{
Id = x.Id,
IsTicket = x.IsTicket,
Name = x.Name,
Price = x.Price,
SaleItems = x.SaleItems,
SessionStartTime = x.SessionStartTime,
DateCreated = x.DateCreated,
DateEdit = x.DateEdit,
UserIdCreated = x.UserIdCreated,
UserIdEdited = x.UserIdEdited,
// calculate stock in subquery
Stock = _context.Tickets.Count(
t => t.StartTime.Date == ticketDate
&& x.SessionStartTime.HasValue
&& t.StartTime.Hour == x.SessionStartTime.Value.Hours // this is the part that is failing
&& t.State != TicketState.Canceled)
}).ToListAsync();
t.StartTime is Datetime and x.SessionStartTime is Nullable Timespan
So when I comment the line && t.StartTime.Hour == x.SessionStartTime.Value.Hours everything is fine, but with it I get warnings that it could not be translated and will be evaluated locally. But I don't want to download the whole ticket table just to count them.
The t.StartTime.Hour part is fine, I tried to perform static comparisons with both parameters. t.StartTime.Hour == 5 was translated without any problems, but x.SessionStartTime.Value.Hours == 5 failed to translate.
Also the problematic part in the application output:
([t].StartTime.Hour == Convert([x].SessionStartTime, TimeSpan).Hours))
So I guess that convert part is failing.
So what I'm missing and how I could work around this problem. Any help will be appreciated.
Update:
After experimenting a bit I have found two workarounds, that I wouldn't call the answers.
First I noticed that EF is trying to convert Nullable<TimeSpan> to a regular TimeSpan from the mentioned output: ([t].StartTime.Hour == Convert([x].SessionStartTime, TimeSpan).Hours))
I thought I could prevent that conversion by converting to a string and comparing the strings (I have a feeling this will bite me in the future):
t.StartTime.ToString().Contains(x.SessionStartTime.ToString())
The second workaround is only viable for my scenario since I know the items query is final and I can materialise it without calculated Stock, and then loop through the results and calculate it on a separate query. But this seems to add additional calls to the database and sacrifice some performance.
foreach(var x in items.Where(x=>x.SessionStartTime.HasValue))
{
// accessing the t.StartTime.TimeOfDay property seems to fail the LINQ to SQL as well
var hours = x.SessionStartTime.Value.Hours;
var minutes = x.SessionStartTime.Value.Minutes;
x.Stock = _context.Tickets.Count(t => t.StartTime.Date == ticketDate
&& t.StartTime.Hour == hours
&& t.StartTime.Minute == minutes);
}
Given:
class Point {
int x;
int y;
}
List<Point> points;
How can I check that property x in a list of Points is greather than a value? I aim something similar to:
assertThat(points).extracting("x").isGreatherThan(20)
However I can't find 'isGreatherThan' after 'extracting'
Update
I don't aim writing custom conditions for this kind of value checking, as assertj already has methods for checking numbers.
Thanks
You can use filteredOn as it supports java 8 Predicate, e.g:
assertThat(listOfPoints).filteredOn(p -> p.x > 20).isNotEmpty();
If you want to do more complex stuff, using Condition is the way to go, in AssertJ 3.x they are simpler to write, rewriting Florian Schaetz example:
Condition<Integer> greaterThan20 = new Condition<>(v -> v.intValue() > 20, "greater than 20");
You can try this one...
.extracting( "x", Integer.class ).areAtLeast( 1, greaterThan20 );
Of course you'll have to write the condition yourself, something like...
final Condition<Integer> greaterThan20 = new Condition<Integer>("greater than 20") {
#Override
public boolean matches(Integer value) {
return value.intValue() > 20;
}
};
In Java 8 you can do something like this:
assertThat(listOfPoints.stream().filter(p->p.x > 20).toArray()).hasSameSizeAs(listOfPoints);
That's for the case where you want ALL points to have x > 20.
To verify that there's at least one (as in Florian Schaetz's answer):
assertThat(listOfPoints.stream().filter(p->p.x > 20).toArray()).isNotEmpty();
I have a problem that has taken me weeks to resolve and I have not been able to.
I have a class where I have two methods. The following is supposed to take the latest date from database. That date represents the latest payment that a customer has done to "something":
public DateTime getLatestPaymentDate(int? idCustomer)
{
DateTime lastDate;
lastDate = (from fp in ge.Payments
from cst in ge.Customers
from brs in ge.Records.AsEnumerable()
where (cst.idCustomer == brs.idCustomer && brs.idHardBox == fp.idHardbox
&& cst.idCustomer == idCustomer)
select fp.datePayment).AsEnumerable().Max();
return lastDate;
}//getLatestPaymentDate
And here I have the other method, which is supposed to call the previous one to complete a Linq query and pass it to a Crystal Report:
//Linq query to retrieve all those customers'data who have not paid their safebox(es) annuity in the last year.
public List<ReportObject> GetPendingPayers()
{
List<ReportObject> defaulterCustomers;
defaulterCustomers = (from c in ge.Customer
from br in ge.Records
from p in ge.Payments
where (c.idCustomer == br.idCustomer
&& br.idHardBox == p.idHardBox)
select new ReportObject
{
CustomerId = c.idCustomer,
CustomerName = c.nameCustomer,
HardBoxDateRecord = br.idHardRecord,
PaymentDate = getLatestPaymentDate(c.idCustomer),
}).Distinct().ToList();
}//GetPendingPayers
No compile error is thrown here, but when I run the application and the second method tries to call the first one in the field PaymentDate the error mentioned in the header occurs:
Linq to Entities does not recognize the method System.DateTime.. and cannot translate this into a store expression
Please anybody with an useful input that put me off from this messy error? Any help will be appreciated !
Thanks a lot !
Have a look at these other questions :
LINQ to Entities does not recognize the method
LINQ to Entities does not recognize the method 'System.DateTime Parse(System.String)' method
Basically, you cannot use a value on the C# side and translate it into SQL. The first question offers a more thorough explanation ; the second offers a simple solution to your problem.
EDIT :
Simply put : the EF is asking the SQL server to perform the getLatestPaymentDate method, which it has no clue about. You need to execute it on the program side.
Simply perform your query first, put the results into a list and then do your Select on the in-memory list :
List<ReportObject> defaulterCustomers;
var queryResult = (from c in ge.Customer
from br in ge.Records
from p in ge.Payments
where (c.idCustomer == br.idCustomer
&& br.idHardBox == p.idHardBox)).Distinct().ToList();
defaulterCustomers = from r in queryResult
select new ReportObject
{
CustomerId = r.idCustomer,
CustomerName = r.nameCustomer,
HardBoxDateRecord = r.idHardRecord,
PaymentDate = getLatestPaymentDate(r.idCustomer),
}).Distinct().ToList();
I don't have access to your code, obviously, so try it out and tell me if it works for you!
You'll end up with an in-memory list
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 1 year ago.
The community reviewed whether to reopen this question 1 year ago and left it closed:
Original close reason(s) were not resolved
Improve this question
What is the best way to check if an object exists in the database from a performance point of view? I'm using Entity Framework 1.0 (ASP.NET 3.5 SP1).
If you don't want to execute SQL directly, the best way is to use Any(). This is because Any() will return as soon as it finds a match. Another option is Count(), but this might need to check every row before returning.
Here's an example of how to use it:
if (context.MyEntity.Any(o => o.Id == idToMatch))
{
// Match!
}
And in vb.net
If context.MyEntity.Any(function(o) o.Id = idToMatch) Then
' Match!
End If
From a performance point of view, I guess that a direct SQL query using the EXISTS command would be appropriate. See here for how to execute SQL directly in Entity Framework: http://blogs.microsoft.co.il/blogs/gilf/archive/2009/11/25/execute-t-sql-statements-in-entity-framework-4.aspx
I had to manage a scenario where the percentage of duplicates being provided in the new data records was very high, and so many thousands of database calls were being made to check for duplicates (so the CPU sent a lot of time at 100%). In the end I decided to keep the last 100,000 records cached in memory. This way I could check for duplicates against the cached records which was extremely fast when compared to a LINQ query against the SQL database, and then write any genuinely new records to the database (as well as add them to the data cache, which I also sorted and trimmed to keep its length manageable).
Note that the raw data was a CSV file that contained many individual records that had to be parsed. The records in each consecutive file (which came at a rate of about 1 every 5 minutes) overlapped considerably, hence the high percentage of duplicates.
In short, if you have timestamped raw data coming in, pretty much in order, then using a memory cache might help with the record duplication check.
I know this is a very old thread but just incase someone like myself needs this solution but in VB.NET here's what I used base on the answers above.
Private Function ValidateUniquePayroll(PropertyToCheck As String) As Boolean
// Return true if Username is Unique
Dim rtnValue = False
Dim context = New CPMModel.CPMEntities
If (context.Employees.Any()) Then ' Check if there are "any" records in the Employee table
Dim employee = From c In context.Employees Select c.PayrollNumber ' Select just the PayrollNumber column to work with
For Each item As Object In employee ' Loop through each employee in the Employees entity
If (item = PropertyToCheck) Then ' Check if PayrollNumber in current row matches PropertyToCheck
// Found a match, throw exception and return False
rtnValue = False
Exit For
Else
// No matches, return True (Unique)
rtnValue = True
End If
Next
Else
// The is currently no employees in the person entity so return True (Unqiue)
rtnValue = True
End If
Return rtnValue
End Function
I had some trouble with this - my EntityKey consists of three properties (PK with 3 columns) and I didn't want to check each of the columns because that would be ugly.
I thought about a solution that works all time with all entities.
Another reason for this is I don't like to catch UpdateExceptions every time.
A little bit of Reflection is needed to get the values of the key properties.
The code is implemented as an extension to simplify the usage as:
context.EntityExists<MyEntityType>(item);
Have a look:
public static bool EntityExists<T>(this ObjectContext context, T entity)
where T : EntityObject
{
object value;
var entityKeyValues = new List<KeyValuePair<string, object>>();
var objectSet = context.CreateObjectSet<T>().EntitySet;
foreach (var member in objectSet.ElementType.KeyMembers)
{
var info = entity.GetType().GetProperty(member.Name);
var tempValue = info.GetValue(entity, null);
var pair = new KeyValuePair<string, object>(member.Name, tempValue);
entityKeyValues.Add(pair);
}
var key = new EntityKey(objectSet.EntityContainer.Name + "." + objectSet.Name, entityKeyValues);
if (context.TryGetObjectByKey(key, out value))
{
return value != null;
}
return false;
}
I just check if object is null , it works 100% for me
try
{
var ID = Convert.ToInt32(Request.Params["ID"]);
var Cert = (from cert in db.TblCompCertUploads where cert.CertID == ID select cert).FirstOrDefault();
if (Cert != null)
{
db.TblCompCertUploads.DeleteObject(Cert);
db.SaveChanges();
ViewBag.Msg = "Deleted Successfully";
}
else
{
ViewBag.Msg = "Not Found !!";
}
}
catch
{
ViewBag.Msg = "Something Went wrong";
}
Why not do it?
var result= ctx.table.Where(x => x.UserName == "Value").FirstOrDefault();
if(result?.field == value)
{
// Match!
}
Best way to do it
Regardless of what your object is and for what table in the database the only thing you need to have is the primary key in the object.
C# Code
var dbValue = EntityObject.Entry(obj).GetDatabaseValues();
if (dbValue == null)
{
Don't exist
}
VB.NET Code
Dim dbValue = EntityObject.Entry(obj).GetDatabaseValues()
If dbValue Is Nothing Then
Don't exist
End If