Neo4jClient Node/Relationship Class conventions - c#

Is there a standard naming convention for the properties/methods of a node/relationship class when working with Neo4jClient?
I'm following this link Neo4jClient - Retrieving relationship from Cypher query to create my relationship class
However, there are certain properties of my relationship which i can't get any value despite the relationship having it. While debugging my code, i realized certain properties was not retrieved from the relationship when creating the relationship object.
this is my relationship class
public class Creates
{
private string _raw;
private int _sourcePort;
private string _image;
private int _DestinationPort;
private int _eventcode;
private string _name;
private string _src_ip;
private int _src_port;
private string _dvc;
private int _signature_ID;
private string _dest_ip;
private string _computer;
private string _sourceType;
private int _recordID;
private int _processID;
private DateTime _time;
private int _dest_port;
public string Raw { get { return _raw; } set { _raw = value; } }
public int SourcePort { get { return _sourcePort; } set { _sourcePort = value; } }
public string Image { get { return _image; } set { _image = value; } }
public int DestinationPort { get { return _DestinationPort; } set { _DestinationPort = value; } }
public int Eventcode { get { return _eventcode; } set { _eventcode = value; } }
public string Name { get { return _name; } set { _name = value; } }
public string Src_ip { get { return _src_ip; } set { _src_ip = value; } }
public int Src_port { get { return _src_port; } set { _src_port = value; } }
public string DVC { get { return _dvc; } set { _dvc = value; } }
public int Signature_ID { get { return _signature_ID; } set { _signature_ID = value; } }
public string Dest_ip { get { return _dest_ip; } set { _dest_ip = value; } }
public string Computer { get { return _computer; } set { _computer = value; } }
public string SourceType { get { return _sourceType; } set { _sourceType = value; } }
public int RecordID { get { return _recordID; } set { _recordID = value; } }
public int ProcessID { get { return _processID; } set { _processID = value; } }
public DateTime Indextime { get { return _time; } set { _time = value; } }
public int Dest_port { get { return _dest_port; } set { _dest_port = value; } }
}
This is another class
public class ProcessConnectedIP
{
public Neo4jClient.RelationshipInstance<Pivot> bindto { get; set; }
public Neo4jClient.Node<LogEvent> bindip { get; set; }
public Neo4jClient.RelationshipInstance<Pivot> connectto { get; set; }
public Neo4jClient.Node<LogEvent> connectip { get; set; }
}
This is my neo4jclient query to get the relationship object
public IEnumerable<ProcessConnectedIP> GetConnectedIPs(string nodeName)
{
try
{
var result =
this.client.Cypher.Match("(sourceNode:Process{name:{nameParam}})-[b:Bind_IP]->(bind:IP_Address)-[c:Connect_IP]->(connect:IP_Address)")
.WithParam("nameParam", nodeName)
.Where("b.dest_ip = c.dest_ip")
.AndWhere("c.Image=~{imageParam}")
.WithParam("imageParam", $".*" + nodeName + ".*")
.Return((b, bind, c, connect) => new ProcessConnectedIP
{
bindto = b.As<RelationshipInstance<Creates>>(),
bindip = bind.As<Node<LogEvent>>(),
connectto = c.As<RelationshipInstance<Creates>>(),
connectip = connect.As<Node<LogEvent>>()
})
.Results;
return result;
}catch(Exception ex)
{
Console.WriteLine("GetConnectedIPs: Error Msg: " + ex.Message);
return null;
}
}
This is the method to read the results
public void MyMethod(string name)
{
IEnumerable<ProcessConnectedIP> result = clientDAL.GetConnectedIPs(name);
if(result != null)
{
var results = result.ToList();
Console.WriteLine(results.Count());
foreach (ProcessConnectedIP item in results)
{
Console.WriteLine(item.Data.Src_ip);
Console.WriteLine(item.bindto.StartNodeReference.Id);
Console.WriteLine(item.bindto.EndNodeReference.Id);
Console.WriteLine(item.connectto.StartNodeReference.Id);
Console.WriteLine(item.connectto.EndNodeReference.Id);
Node<LogEvent> ans = item.bindip;
LogEvent log = ans.Data;
Console.WriteLine(log.Name);
Node<LogEvent> ans1 = item.connectip;
LogEvent log1 = ans1.Data;
Console.WriteLine(log1.Name);
}
}
}
Somehow, i'm only able to populate the relationship object with src_ip/src_port/dest_ip/dest_port values. the rest are empty.
Is there any possible reason why? I've played with upper/lower cases on the properties names but it does not seem to work.
This is the section of the graph im working with
This is the relationship properties sample:
_raw: Some XML dataSourcePort: 49767Image: C:\Windows\explorer.exeDestinationPort: 443EventCode: 3Name: Bind
IPsrc_ip: 172.10.10.104dvc: COMPUTER-NAMEsrc_port:
49767signature_id: 3dest_ip: 172.10.10.11Computer:
COMPUTRE-NAME_sourcetype:
XmlWinEventLog:Microsoft-Windows-Sysmon/OperationalRecordID:
13405621ProcessId: 7184_time: 2017-08-28T15:15:39+08:00dest_port: 443

I'm not entirely sure how your Creates class is ever populated, in particular those fields - as your Src_port property doesn't match the src_port in the sample you provided (case wise).
I think it's probably best to go back to a super simple version. Neo4jClient will map your properties to the properties in the Relationship as long as they have the same name (and it is case-sensitive).
So start with a new Creates class (and use auto properties - it'll make your life a lot easier!)
public class Creates
{
public string Computer { get; set; }
}
Run your query with that and see if you get a result, then keep on adding properties that match the name and type you expect to get back (int, string etc)

It seems that i have to give neo4j node/relationship property names in lowercase and without special characters at the start of the property name, in order for the above codes to work.
The graph was not created by me at the start thus i had to work on it with what was given. I had to get the developer who created the graph to create the nodes with lowercases in order for the above to work.

Related

Why Query returns some null values to my list Object using dapper

I have this functional query where I only used fictive tables names for security concerns :
SELECT
h.CENID,
h.BMHFMC,
h.BMHDONEMIDASSTEP1,
h.BMHDONEMIDASSTEP2,
h.LMIID,
h.BMHHOLD,
h.BMHBATCHMIDAS,
h.BMHFMCVALUEDATE AS HeaderValueDate,
h.SUNID,
h.BRAID,
d.BMHID,
d.BMDRUBRIQUE,
d.BMDCLIENT,
d.BMDSEQUENCE,
d.BMDDATE,
d.BMDDEVISE,
d.BMDMONTANT,
d.BMDTYPE,
d.BMDNOTE,
d.BMDENTRYNBRE,
v.DEVDECIMAL ,
NVL(t.TYPVERIFCOMPTEMIDAS, 0) AS TYPVERIFCOMPTEMIDAS
FROM dbo.TableOne h
INNER JOIN dbo.Tabletwoo d
ON h.BMHID = d.BMHID
INNER JOIN dbo.tableThree v
ON d.BMDDEVISE = v.DEVID
LEFT JOIN dbo.TableFour t
ON t.TYPID=h.BMHFMC
WHERE d.BMDMONTANT != 0
AND h.BMHDONEMIDASSTEP1 = 0
AND h.BMHDONEMIDASSTEP2 = 0
AND h.LMIID = 0
AND h.BMHHOLD = 0
And I made a class in order to bind every fields
public class Batch :BaseRepository ,IList<Batch>
{
public Batch()
{
}
private string cendid;
private string bmhfmc;
private double bmhdonemidasstep1;
private double bmhdonemidasstep2;
private double lmiid;
private double bmhhold;
private double bmhbatchmidas;
private DateTime headervaluedateordinal;
private double sunid; //
private string bradid; //
private double bmhid;
private string bmdrubirique; //
private string bmdclient;
private string bmdsequence;
private DateTime bmddate;
private string bmddevise;
private double bmdmontant;
private string bmdtype;
private string bmdnote;
private string bmdentrynbre; //
private double devdecimalordinal;
private double typverifcomptemidasordinal;
public Batch(string cendid, string bmhfmc, double bmhdonemidasstep1, double bmhdonemidasstep2, double lmiid, double bmhhold, double bmhbatchmidas, DateTime headervaluedateordinal, double sunid, string bradid, double bmhid, string bmdrubirique, string bmdclient, string bmdsequence, DateTime bmddate, string bmddevise, double bmdmontant, string bmdtype, string bmdnote, string bmdentrynbre, double devdecimalordinal, double typverifcomptemidasordinal)
{
this.cendid = cendid;
this.bmhfmc = bmhfmc;
this.bmhdonemidasstep1 = bmhdonemidasstep1;
this.bmhdonemidasstep2 = bmhdonemidasstep2;
this.lmiid = lmiid;
this.bmhhold = bmhhold;
this.bmhbatchmidas = bmhbatchmidas;
this.headervaluedateordinal = headervaluedateordinal;
this.sunid = sunid;
this.bradid = bradid;
this.bmhid = bmhid;
this.bmdrubirique = bmdrubirique;
this.bmdclient = bmdclient;
this.bmdsequence = bmdsequence;
this.bmddate = bmddate;
this.bmddevise = bmddevise;
this.bmdmontant = bmdmontant;
this.bmdtype = bmdtype;
this.bmdnote = bmdnote;
this.bmdentrynbre = bmdentrynbre;
this.devdecimalordinal = devdecimalordinal;
this.typverifcomptemidasordinal = typverifcomptemidasordinal;
}
public string Cendid
{
get { return cendid; }
set { cendid = value; }
}
public string Bmhfmc
{
get { return bmhfmc; }
set { bmhfmc = value; }
}
public double Bmhdonemidasstep1
{
get { return bmhdonemidasstep1; }
set { bmhdonemidasstep1 = value; }
}
public double Bmhdonemidasstep2
{
get { return bmhdonemidasstep2; }
set { bmhdonemidasstep2 = value; }
}
public double Lmiid
{
get { return lmiid; }
set { lmiid = value; }
}
public double Bmhhold
{
get { return bmhhold; }
set { bmhhold = value; }
}
public double Bmhbatchmidas
{
get { return bmhbatchmidas; }
set { bmhbatchmidas = value; }
}
public DateTime Headervaluedateordinal
{
get { return headervaluedateordinal; }
set { headervaluedateordinal = value; }
}
public double Sunid
{
get { return sunid; }
set { sunid = value; }
}
public string Bradid
{
get { return bradid; }
set { bradid = value; }
}
public double Bmhid
{
get { return bmhid; }
set { bmhid = value; }
}
public string Bmdrubirique
{
get { return bmdrubirique; }
set { bmdrubirique = value; }
}
public string Bmdclient
{
get { return bmdclient; }
set { bmdclient = value; }
}
public string Bmdsequence
{
get { return bmdsequence; }
set { bmdsequence = value; }
}
public DateTime Bmddate
{
get { return bmddate; }
set { bmddate = value; }
}
public string Bmddevise
{
get { return bmddevise; }
set { bmddevise = value; }
}
public double Bmdmontant
{
get { return bmdmontant; }
set { bmdmontant = value; }
}
public string Bmdtype
{
get { return bmdtype; }
set { bmdtype = value; }
}
public string Bmdnote
{
get { return bmdnote; }
set { bmdnote = value; }
}
public string Bmdentrynbre
{
get { return bmdentrynbre; }
set { bmdentrynbre = value; }
}
public double Devdecimalordinal
{
get { return devdecimalordinal; }
set { devdecimalordinal = value; }
}
public double Typverifcomptemidasordinal
{
get { return typverifcomptemidasordinal; }
set { typverifcomptemidasordinal = value; }
}
Now when I execute the query into a list using dapper
Connection conn = new Connection();
OracleConnection connection = conn.GetDBConnection();
myList= connection.Query<Batch>(querySql).ToList();
Now,while debugging, all fields returns the expected values .But, I noticed those fields below are null in myList not empty but really null , but the problem is they aren't null in the database
Bmdrubirique , Sunid, Bmdentrynbre, Bradid ,Cenid
In oracle database those fields are like the following :
CENID is VARCHAR2(3 BYTE)`
Bmhid is VARCHAR2(3 BYTE)
Sunid is NUMBER(38,0)
Bradid is VARCHAR2(3 BYTE)
I don't get it , where did it go wrong? why other fields are properly loaded while those returns null value ?
My default assumption would be that there is a typo in the real code and the constructor is assigning a value from a field to itself. However, frankly: since you have a public Batch() {} constructor, I'm not sure what the benefit of the second one is - it just adds risk of errors. Likewise with the fields and manual properties.
So if this as me, where you currently have (simplified to two properties):
public class Batch
{
private string cendid;
private string bmhfmc;
public Batch() {}
public Batch(string cendid, string bmhfmc)
{
this.cendid = cendid;
this.bmhfmc = bmhfmc;
}
public string Cendid
{
get { return cendid; }
set { cendid = value; }
}
public string Bmhfmc
{
get { return bmhfmc; }
set { bmhfmc = value; }
}
}
I would have literally just:
public class Batch
{
public string Cendid {get;set;}
public string Bmhfmc {get;set;}
}
All of the rest of the code is just opportunities to make coding errors.
Now: the reason that Cendid is null is because: the column is CENID - only one d. This means that dapper isn't even using your custom constructor, because it isn't a perfect match between the constructor and the columns. Ditto the other fields like BRAID vs BRADID.
So the next thing to do is to fix the typos.

Creating two C# class definitions with a driver to test classes, but not sure why so many errors?

I am new to C# and was asked to create two class definitions (customer and order) using partial code and with the suggested class names, methods, contructors and following an example. I am not sure why I am getting so many errors when I build/debug?
After this is finished, I need to create another program that builds onto this one. Our instructor also asked us not to use validation...
Some of my most common errors are:
expected: ; (in a place in my code where I believe there should not be a semi-colon and
Error "Expected class, delegate, enum, interface, or struct.
Here is my code:
public class clsOrder
{
//declare class variables
protected string cstrDescription;
protected int cintQuantity;
protected decimal cdecPrice;
protected decimal cdecExtendedPrice;
//shared variables
static decimal cdecTotalPrice;
static int cintTotalCount;
//declare constructors
public clsOrder();
}
public clsOrde r(string strDescription,
int intQuantity, decimal decPrice)
}
//declare property methods
{
this.Description = string strDescription;
this.Quantity = int intQuantity;
this.Price = decimal decPrice;
//declare read-only properties
public decimal ExtendedPrice
}
public string Description
{
get
{
return strDescription;
}
set
{
strDescription = value;
}
}
public int Quantity
{
get
{
return intQuantity;
}
set
{
intQuantity = value;
}
}
public decimal Price
{
get
{
return decPrice;
}
set
{
decPrice = value;
}
}
get
{
return cdecExtendedPrice;
}
}
//declare Shared (static) ReadOnly Properites
public static decimal TotalPrice
{
get
{
return cdecTotalPrice;
}
}
public static int TotalCount
{
get
{
return cintTotalCount;
}
}
//declare supporting methods
public void calcExtendedPrice()
{
cdecExtendedPrice = cintQuantity * cdecPrice;
}
public void accumulateTotals()
{
cdecTotalPrice += cdecExtendedPrice;
cintTotalCount += 1;
}
public static void resetTotals()
{
cdecTotalPrice = 0;
cintTotalCount = 0;
}
}//end of Class
}//end of namespace
And
public class clsCustomer
{
//declare class variables
private string cstrName;
private string cstrStreet;
private string cstrCity;
private string cstrState;
private string cstrZip;
//declare constructors
public class clsCustomer()
}
public clsCustomer(string strName,
string strStreet, string strCity,
string strState, string strZip)
}
//declare property methods
{
this.Name = cstrName;
this.Street = cstrStreet;
this.City = cstrCity;
this.State = cstrState;
this.Zip = cstrZip;
}
public string Name
{
get
{
return cstrName;
}
set
{
cstrName = value;
}
}
public string Street
{
get
{
return cstrStreet;
}
set
{
cstrStreet = value;
}
}
public string City
{
get
{
return cstrCity;
}
set
{
cstrCity = value;
}
}
public string State
{
get
{
return cstrState;
}
set
{
cstrState = value;
}
}
public string Zip
{
get
{
return cstrZip;
}
set
{
cstringZip = value;
}
}
Any help would be very much appreciated, thank you.

AutoMapper Ignore() Issue

Okay, I'm hoping I am just somehow overlooking the obvious. I have the following code situation below. For some reason, the SequenceNo property is still getting mapped even though I'm calling Ignore(). I'm using the latest. I also had tested it with two different classes in the same project and it seemed to work, so what's wrong with this scenario then?
This is the domain object:
public class CableID
{
private string _panelID1;
public string PanelID1
{
get { return _panelID1; }
private set { _panelID1 = value; }
}
private string _panelID2;
public string PanelID2
{
get { return _panelID2; }
private set { _panelID2 = value; }
}
private int _sequenceNo;
public int SequenceNo
{
get { return _sequenceNo; }
private set { _sequenceNo = value; }
}
private DateTime _inService;
public DateTime InService
{
get { return _inService; }
set { _inService = value; }
}
private string _id;
public string ID
{
get { return _id; }
private set { _id = value; }
}
public CableID(string panelID1, string panelID2, int sequenceNo)
{
this.PanelID1 = panelID1;
this.PanelID2 = panelID2;
this.SequenceNo = sequenceNo;
this.ID = string.Format("({0}-{1}){2}", this.PanelID1, this.PanelID2, this.SequenceNo);
}
public CableID(string id)
{
if (string.IsNullOrEmpty(id))
throw new ArgumentNullException("id");
this.ID = id;
}
}
And here is the DTO Object:
public class CableIDDTO
{
private string _panelID1;
public string PanelID1
{
get { return _panelID1; }
set { _panelID1 = value; }
}
private string _panelID2;
public string PanelID2
{
get { return _panelID2; }
set { _panelID2 = value; }
}
private int _sequenceNo;
public int SequenceNo
{
get { return _sequenceNo; }
set { _sequenceNo = value; }
}
private string _id;
public string ID
{
get { return _id; }
set { _id = value; }
}
public CableIDDTO()
{ }
public CableIDDTO(string panelID1, string panelID2, int sequenceNo)
{
this.PanelID2 = panelID1;
this.PanelID1 = panelID2;
this.SequenceNo = sequenceNo;
this.ID = string.Format("({0}-{1}){2}", this.PanelID2, this.PanelID1, this.SequenceNo);
}
}
And finally the AutoMapper use-case:
CableID cableID = new CableID("A1", "B1", 2);
Mapper.CreateMap<CableID, CableIDDTO>()
.ForMember(dest => dest.SequenceNo, opt => opt.Ignore());
CableIDDTO dto = Mapper.Map<CableID, CableIDDTO>(cableID);
dto.SequenceNo = 2 when since I had set the Ignore() it should be 0.
This is because AutoMapper is finding this CableIDDTO constructor:
public CableIDDTO(string panelID1, string panelID2, int sequenceNo)
and calling it, setting sequenceNo. I'm not exactly sure how or why it's doing that--i'll continue to dig.
You can fix this by calling .ConstructUsing and telling AutoMapper to use the no-args constructor:
Mapper.CreateMap<CableID, CableIDDTO>()
.ConstructUsing((Func<CableID, CableIDDTO>)(src => new CableIDDTO()))
.ForMember(dest => dest.SequenceNo, opt => opt.Ignore());
Upon further research, this looks like a feature in AutoMapper that tries to match up source property names with destination constructors. Since your destination type (CableIDDTO) had a constructor that perfectly matched up with several property names on the source (panelID1, panelID2, sequenceNo), that constructor was called.
Another way to disable this feature is to call DisableConstructorMapping:
Mapper.Configuration.DisableConstructorMapping()

JsonConvert.SerializeObject() fails in serializing class with DateTime fields

I'm having a class with only private fields and their public getter-setters. I need to convert class object into JSON String hence I'm using JSON.Net.
Following is a simple snippet to convert class object into a JSON string.
MyClass obj = new MyClass();
string json = JsonConvert.SerializeObject(obj);
Console.WriteLine(json);
But the method SerializeObject throws StackOverflowException at field in MyClass of type DateTime. What's happening here?
Update
Following is how MyClass looks like (as it is, I don't mind sharing the actual class)
class MyClass
{
private int _Model;
public int Model
{
get
{
return _Model;
}
set
{
_Model = value;
}
}
private long _ProductionControlNumber;
public long ProductionControlNumber
{
get
{
return _ProductionControlNumber;
}
set
{
_ProductionControlNumber = value;
}
}
private DateTime _ProductionDate;
public DateTime ProductionDate
{
get
{
return _ProductionDate;
}
set
{
_ProductionDate = value;
}
}
private DateTime _TestDate;
public DateTime TestDate
{
get
{
return _TestDate;
}
set
{
_TestDate = value;
}
}
private DateTime _TestStartTime;
public DateTime TestStartTime
{
get
{
return _TestStartTime;
}
set
{
_TestStartTime = value;
}
}
private TimeSpan _TestDuration;
public TimeSpan TestDuration
{
get
{
return _TestDuration;
}
set
{
_TestDuration = value;
}
}
public DateTime TestEndTime
{
get
{
//TODO Perform start end time computing logic.
return TestEndTime;
}
}
private int _TestBed;
public int TestBed
{
get
{
return _TestBed;
}
set
{
_TestBed = value;
}
}
private long _EngineSerial;
public long EngineSerial
{
get
{
return _EngineSerial;
}
set
{
_EngineSerial = value;
}
}
private Single _FuelSpecificGravity;
public Single FuelSpecificGravity
{
get
{
return _FuelSpecificGravity;
}
set
{
_FuelSpecificGravity = value;
}
}
private long _FuelConsume100;
public long FuelConsume100
{
get
{
return _FuelConsume100;
}
set
{
_FuelConsume100 = value;
}
}
private long _FuelConsume110;
public long FuelConsume110
{
get
{
return _FuelConsume100;
}
set
{
_FuelConsume100 = value;
}
}
private int _TemporaryRPM;
public int TemporaryRPM
{
get
{
return _TemporaryRPM;
}
set
{
_TemporaryRPM = value;
}
}
private int _PermanentRPM;
public int PermanentRPM
{
get
{
return _PermanentRPM;
}
set
{
_PermanentRPM = value;
}
}
private Single _RatedPower;
public Single RatedPower
{
get
{
return _RatedPower;
}
set
{
_RatedPower = value;
}
}
private int _RatedSpeed;
public int RatedSpeed
{
get
{
return _RatedSpeed;
}
set
{
_RatedSpeed = value;
}
}
private double _PulleyDiameter;
public double PulleyDiameter
{
get
{
return _PulleyDiameter;
}
set
{
_PulleyDiameter = value;
}
}
private double _RopeDiameter;
public double RopeDiameter
{
get
{
return _RopeDiameter;
}
set
{
_RopeDiameter = value;
}
}
private Single _FullLoad;
public Single FullLoad
{
get
{
return _FullLoad;
}
set
{
_FullLoad = value;
}
}
}
Also, I'll have another class which will have MyClass type field (along with its own similar set of fields), which is going to be converted into JSON string too, and that shouldn't be a problem since JSON.Net is said to support that situation too.
Note: I'm new to C# but I've previously worked with JSON in Java, where I get to play with JSONObject and JSONArray, and they were pretty straight forward.
It looks like your TestEndTime property's getter references itself. Therefore when Json.NET tries to serialize it, it recursively accesses itself and causes the StackOverflowException.
Hope that helps!

What is the proper way to handle an array of one class in another class?

Here are two simple classes to illustrate my question:
class Widget
{
private int _widgetID;
public int WidgetID
{
get { return _widgetID; }
set { _widgetID = value; }
}
private int _categoryID;
public int CategoryID
{
get { return _categoryID; }
set { _categoryID = value; }
}
private string _widgetName;
public string WidgetName
{
get { return _widgetName; }
set { _widgetName = value; }
}
}
And them the second class:
class WidgetCategory
{
private int _widgetCategoryID;
public int WidgetCategoryID
{
get { return _widgetCategoryID; }
set { _widgetCategoryID = value; }
}
private Widget[] _widgets;
public Widget[] Widgets
{
get { return _widgets; }
set { _widgets = value; }
}
private string _widgetCategoryName;
public string WidgetCategoryName
{
get { return _widgetCategoryName; }
set { _widgetCategoryName = value; }
}
}
How would I handle this situation in the most efficient way?
Also, so you know, I will need to nest other classes the same way below the Widget class.
You should create a read-only property of type System.Collections.ObjectModel.Collection<Widget>.
Collection properties should be read only
Use Collection<T>

Categories

Resources