I have an ASP.NET Web Forms project which is using Readify-Neo4jClient and Neo4J Community 2.0.3, I'm getting a bug where a number stored in the database is changing its value when retrieved. Here is a picture of what’s in the database and what I can see in VS2013:
https://docs.google.com/file/d/0B6b_N7sDgjmvMVF5TFpaZXJmNFk/edit
The code to retrieve the user is as follows:
IEnumerable<SUser> FoundUsers = Neo4jGraphClient.Cypher.Match("(user:User)")
.Where((SUser user) => user.Email == UserName)
.Return(user => user.As<SUser>())
.Results;
Code to write to the database is as follows:
long DateTimeNow = DateTime.Now.Ticks;
SUser ss = new SUser
{
Id = UserCounter.SubmitAndCommitNewUser(),
DateOfBirth = DobDay.Text + "" + DobMonth.Text + "" + DobYear.Text,
Email = UserName.Text,
FirstName = FirstName.Text,
LastName = LastName.Text,
UserCreatedOn = DateTimeNow,
role = UType.ADMIN,
Status = UStatus.NEW
};
Neo4jReq.CreateSUser(ss);
......
public static SUser CrseateSUser(SUser NewUser)
{
//...
Neo4jGraphClient.Cypher
.Create("(user:User {NewUser})")
.WithParam("NewUser", NewUser)
.ExecuteWithoutResults();
existing = NewUser;
}
Class is as follows:
public class SUser
{
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string DateOfBirth { get; set; }
public string Email { get; set; }
public UType role { get; set; }
public UStatus Status { get; set; }
public string pass { get; set; }
public string VerificationGUID { get; set; }
public long UserCreatedOn { get; set; }
public string UserNotes { get; set; }
}
Any ideas on whats causing this?
Right - I've got this replicating, this looks like a bug(?) in the way the Neo4j browser shows the data (both the current and older webadmin), so the data stored in Neo4j is correct, but it's getting 'rounded' (in a sense anyway) in the display, if you run the 'Get' query in the browser you get the '00' ending, this also happens in the old web admin:
http://localhost:7474/webadmin/
if you run the query in the 'Data Browser'.
However, if you run the query in the Console (http://localhost:7474/webadmin/#/console/) you'll get the correct results. Neo4jClient is giving you the right results, it's the browser that is wrong in this case.
Related
I am cassandra for custom logging my .netcore project, i am using CassandraCSharpDriver.
Problem:
I have created UDT for params in log, and added list of paramUDT in Log table as frozen.
But i am getting error: Non-frozen UDTs are not allowed inside collections. I don't know why ia m getting this error because i am using Frozen attribute on list i am using in Log Model.
logSession.Execute($"CREATE TYPE IF NOT EXISTS {options.Keyspaces.Log}.{nameof(LogParamsCUDT)} (Key text, ValueString text);");
Here is model:
public class Log
{
public int LoggingLevel { get; set; }
public Guid UserId { get; set; }
public string TimeZone { get; set; }
public string Text { get; set; }
[Frozen]
public IEnumerable<LogParamsCUDT> LogParams { get; set; }
}
Question where i am doing wrong, is my UDT script not correct or need to change in model.
Thanks in advance
I've tried using that model and Table.CreateIfNotExists ran successfully.
Here is the the code:
public class Program
{
public static void Main()
{
var cluster = Cluster.Builder().AddContactPoint("127.0.0.1").Build();
var session = cluster.Connect();
session.CreateKeyspaceIfNotExists("testks");
session.ChangeKeyspace("testks");
session.Execute($"CREATE TYPE IF NOT EXISTS testks.{nameof(LogParamsCUDT)} (Key text, ValueString text);");
session.UserDefinedTypes.Define(UdtMap.For<LogParamsCUDT>($"{nameof(LogParamsCUDT)}", "testks"));
var table = new Table<Log>(session);
table.CreateIfNotExists();
table.Insert(new Log
{
LoggingLevel = 1,
UserId = Guid.NewGuid(),
TimeZone = "123",
Text = "123",
LogParams = new List<LogParamsCUDT>
{
new LogParamsCUDT
{
Key = "123",
ValueString = "321"
}
}
}).Execute();
var result = table.First(l => l.Text == "123").Execute();
Console.WriteLine(JsonConvert.SerializeObject(result));
Console.ReadLine();
table.Where(l => l.Text == "123").Delete().Execute();
}
}
public class Log
{
public int LoggingLevel { get; set; }
public Guid UserId { get; set; }
public string TimeZone { get; set; }
[Cassandra.Mapping.Attributes.PartitionKey]
public string Text { get; set; }
[Frozen]
public IEnumerable<LogParamsCUDT> LogParams { get; set; }
}
public class LogParamsCUDT
{
public string Key { get; set; }
public string ValueString { get; set; }
}
Note that I had to add the PartitionKey attribute or else it wouldn't run.
Here is the CQL statement that it generated:
CREATE TABLE Log (
LoggingLevel int,
UserId uuid,
TimeZone text,
Text text,
LogParams frozen<list<"testks"."logparamscudt">>,
PRIMARY KEY (Text)
)
If I remove the Frozen attribute, then this error occurs: Cassandra.InvalidQueryException: 'Non-frozen collections are not allowed inside collections: list<testks.logparamscudt>'.
If your intention is to have a column like this LogParams frozen<list<"testks"."logparamscudt">> then the Frozen attribute will work. If instead you want only the UDT to be frozen, i.e., LogParams list<frozen<"testks"."logparamscudt">>, then AFAIK the Frozen attribute won't work and you can't rely on the driver to generate the CREATE statement for you.
All my testing was done against cassandra 3.0.18 using the latest C# driver (3.10.1).
I'm using ASP.NET C# with entity framework and I'm trying to upload image for a profile and display it.
Here is the relevant part of the View file (Manage.cshtml)
<input type="file" name="form-register-photo" id="form-register-photo" disabled>
Here is the relevant part of the Controller file (Manage.cs)
[HttpPost]
public ActionResult Manage(ManageViewModel manageviewmodel,HttpPostedFileBase upload)
{
TheFoodyContext db = new TheFoodyContext();
User user_to_update = db.Users.SingleOrDefault(s => s.email == manageviewmodel.Email);
if (ModelState.IsValid)
{
if (user_to_update != null && (upload != null && upload.ContentLength > 0))
{
var fileName = Path.GetFileName(upload.FileName);
var path = Path.Combine(Server.MapPath("~/FOODY"), fileName);
user_to_update.email = manageviewmodel.Email;
user_to_update.fname = manageviewmodel.FirstName;
user_to_update.lname = manageviewmodel.LastName;
user_to_update.phone = manageviewmodel.Phone;
user_to_update.photo = path;
user_to_update.address = manageviewmodel.Address;
user_to_update.city = manageviewmodel.City;
user_to_update.postcode = manageviewmodel.PostCode;
user_to_update.district = manageviewmodel.District;
user_to_update.user_type = manageviewmodel.UserType;
user_to_update.status = manageviewmodel.Status;
db.SaveChanges();
return RedirectToAction("Manage");
}
}
return View(manageviewmodel);
}
Within the above controller i have coded for other fields also. So I want to upload the picture among with them. That means from a single button click.
Here is my Model class (ManageViewModel.cs)
public class ManageViewModel
{
public string FirstName { get; set; }
public string LastName { get; set; }
public string Email { get; set; }
public string Phone { get; set; }
public string Photo { get; set; }
public string Address { get; set; }
public string City { get; set; }
public int PostCode { get; set; }
public string District { get; set; }
public string UserType { get; set; }
public string Status { get; set; }
}
But for this one photo uploading part did not work properly. So I really don't know how to manage this.
Entity Framework doesn't help you to literally upload an image.
From your code, you only just edit 1 record in Users in database, without actually upload the image to hosting drive.
For simple, you will need to have something like below to store the file in physically:
var path = Path.Combine(Server.MapPath("~/FOODY"), fileName);
upload.SaveAs(newSPath);
You didn't show exactly what is the result after this db.SaveChanges(); show I'm not sure whether your photo path getting any error. My suggestion is add in a try catch block and run the code in Debug, see what will you have in user_to_update.photo after db.SaveChanges();
I have some code that is functioning oddly and was wondering if anyone else hase come across this issue.
I have a view model that collects data from a database via a stored procedure and a vb object (no I do not know vb this is legacy)
When I execute the program the data is collected as expected via the controller. When I debug it I can see all of my parameters populating with information. However when it comes to the view it says that the parameters are null. I have included my code
Models:
public class PersonIncomeViewModel
{
public string IncomeTypeDesc { get; set; }
public string IncomeDesc { get; set; }
public string Income { get; set; }
}
public class PersonIncomeListViewModel
{
public int? PersonId { get; set; }
public List<PersonIncomeListItem> Incomes { get; set; }
public PersonIncomeListViewModel()
{
Incomes = new List<PersonIncomeListItem>();
}
}
public class PersonLookupViewModel : Queue.QueueViewModel
{
public int Action { get; set; }
public bool ShowAdvancedFilters { get; set; }
//Person Search Variables
[Display(Name = #"Search")]
public string SpecialSearch { get; set; }
[Display(Name = #"Person Id")]
public int? PersonId { get; set; }
[Display(Name = #"Full Name")]
public string FullName { get; set; }
[Display(Name = #"SSN")]
public string SSN { get; set; }
public string AddressStatus { get; set; }
public string EmploymentStatus { get; set; }
public PersonIncomeViewModel Income { get; set; }
public List<PersonIncomeListItem> Incomes { get; set; }
public PersonLookupViewModel()
{
Income = new PersonIncomeViewModel();
Incomes = new List<PersonIncomeListItem>();
}
}
Controller:
public ActionResult _Income(int id)
{
var vm = new PersonLookupViewModel();
var personManager = new dtPerson_v10_r1.Manager( ref mobjSecurity);
//var person = personManager.GetPersonObject((int)id, vIncludeIncomes: true);
var person = personManager.GetPersonObject(id, vIncludeIncomes: true);
var look = JsonConvert.SerializeObject(person.Incomes);
foreach (dtPerson_v10_r1.Income income in person.Incomes)
{
if (income.IncomeType_ID == 0)
{
var item = new PersonIncomeListItem
{
IncomeTypeDesc = "Unknown",
IncomeDesc = income.IncomeDesc,
Income = mobjFormat.FormatObjectToCurrencyString(income.Income)
};
vm.Incomes.Add(item);
}
if (income.IncomeType_ID == 1)
{
var item = new PersonIncomeListItem
{
IncomeTypeDesc = "Alimony",
IncomeDesc = income.IncomeDesc,
Income = mobjFormat.FormatObjectToCurrencyString(income.Income)
};
vm.Incomes.Add(item);
}
if (income.IncomeType_ID == 2)
{
var item = new PersonIncomeListItem
{
IncomeTypeDesc = "Child Support",
IncomeDesc = income.IncomeDesc,
Income = mobjFormat.FormatObjectToCurrencyString(income.Income)
};
vm.Incomes.Add(item);
}
}
return PartialView(vm);
}
View:
#using dtDataTools_v10_r1
#using ds_iDMS.Models.Person
#model ds_iDMS.Models.Person.PersonLookupViewModel
#{
var format = new dtDataTools_v10_r1.CustomFormat();
var newInitials = (Model.Income.IncomeTypeDesc.First().ToString() + Model.Income.IncomeDesc.First().ToString() + Model.Income.Income.First().ToString()).ToUpper();
}
using (Html.DSResponsiveRow(numberOfInputs: ExtensionMethods.NumberOfInputs.TwoInputs))
{
using (Html.DSCard(ExtensionMethods.Icon.CustomText, iconInitials: newInitials, color: ExtensionMethods.Colors.PrimaryBlue))
{
<div>#Model.Income.IncomeTypeDesc</div>
<div>#Model.Income.IncomeDesc</div>
<div>#Model.Income.Income</div>
}
}
There are some extensions that we have built but they are irrelevant to the issue
The line that errors out is this one:
var newInitials = (Model.Income.IncomeTypeDesc.First().ToString() + Model.Income.IncomeDesc.First().ToString() + Model.Income.Income.First().ToString()).ToUpper();
Which drives all of the extension methods on the view and as I run the debugger over it all of the parameters read null, however like I said when I run the debugger and check them in the controller they are populated properly.
Sorry about the long post but I wanted to ensure all the detail was there
This is how to pass the Object model to your Partial View
return PartialView("YourViewName", vm);
or using the Views path
return PartialView("~/YourView.cshtml", vm);
EDIT
Try starting your Action Method like this
var vm= new Person();
vm.PersonLookupViewModel = new PersonLookupViewModel();
Problem solved I had issues with some of my vb objects and had the vb person take a look at them and she fixed them.
Thank you for all the help
EDIT
What had to happen is the vb object had to be re-written and my logic was just fine as it was in the beginning. I marked the one response to my question as the answer because had it been in true MVC without vb objects attached to it, that would have worked perfectly
I'm looking to be able to reuse some of the transform expressions from indexes so I can perform identical transformations in my service layer when the document is already available.
For example, whether it's by a query or by transforming an existing document at the service layer, I want to produce a ViewModel object with this shape:
public class ClientBrief
{
public int Id { get; set; }
public string FullName { get; set; }
public string Email { get; set; }
// ellided
}
From this document model:
public class Client
{
public int Id { get; private set; }
public CompleteName Name { get; private set; }
public Dictionary<EmailAddressKey, EmailAddress> Emails { get; private set; }
// ellided
}
public class CompleteName
{
public string Title { get; set; }
public string GivenName { get; set; }
public string MiddleName { get; set; }
public string Initials { get; set; }
public string Surname { get; set; }
public string Suffix { get; set; }
public string FullName { get; set; }
}
public enum EmailAddressKey
{
EmailAddress1,
EmailAddress2,
EmailAddress3
}
public class EmailAddress
{
public string Address { get; set; }
public string Name { get; set; }
public string RoutingType { get; set; }
}
I have an expression to transform a full Client document to a ClientBrief view model:
static Expression<Func<IClientSideDatabase, Client, ClientBrief>> ClientBrief = (db, client) =>
new ClientBrief
{
Id = client.Id,
FullName = client.Name.FullName,
Email = client.Emails.Select(x => x.Value.Address).FirstOrDefault()
// ellided
};
This expression is then manipulated using an expression visitor so it can be used as the TransformResults property of an index (Client_Search) which, once it has been generated at application startup, has the following definition in Raven Studio:
Map:
docs.Clients.Select(client => new {
Query = new object[] {
client.Name.FullName,
client.Emails.SelectMany(x => x.Value.Address.Split(new char[] {
'#'
})) // ellided
}
})
(The Query field is analysed.)
Transform:
results.Select(result => new {
result = result,
client = Database.Load(result.Id.ToString())
}).Select(this0 => new {
Id = this0.client.__document_id,
FullName = this0.client.Name.FullName,
Email = DynamicEnumerable.FirstOrDefault(this0.client.Emails.Select(x => x.Value.Address))
})
However, the transformation expression used to create the index can then also be used in the service layer locally when I already have a Client document:
var brief = ClientBrief.Compile().Invoke(null, client);
It allows me to only have to have one piece of code that understands the mapping from Client to ClientBrief, whether that code is running in the database or the client app. It all seems to work ok, except the query results all have an Id of 0.
How can I get the Id property (integer) properly populated in the query?
I've read a number of similar questions here but none of the suggested answers seem to work. (Changing the Ids to strings from integers is not an option.)
I have a hard time following your sample fully, Really the best way to dig in to this would be with a failing self-contained unit test.
Nonetheless, let's see if I can pull out the important bits.
In the transform, you have two areas where you are working with the id:
...
client = Database.Load(result.Id.ToString())
...
Id = this0.client.__document_id,
...
The result.Id in the first line and the Id = in the second line are expected to be integers.
The Database.Load() expects a string document key and that is also what you see in __document_id.
The confusion comes from Raven's documentation, code, and examples all use the terms id and key interchangeably, but this is only true when you use string identifiers. When you use non-string identifiers, such as ints or guids, the id may be 123, but the document key is still clients/123.
So try changing your transform so it translates:
...
client = Database.Load("clients/" + result.Id)
...
Id = int.Parse(this0.client.__document_id.Split("/")[1]),
...
... or whatever the c# equivalent linq form would be.
I have a company that contains an address object. The SQL return is flat, and I'm tring to get Query<> to load all the objects.
cnn.Query<Company,Mailing,Physical,Company>("Sproc",
(org,mail,phy) =>
{
org.Mailing = mail;
org.Physical = phy;
return org;
},
new { ListOfPartyId = stringList }, null, true, commandTimeout: null,
commandType: CommandType.StoredProcedure, splitOn: "MailingId,PhyscialId").ToList();
I'm not sure if i have the SplitOn correct either. I'm getting the message:
When using the multi-mapping APIs ensure you set the splitOn param if
you have keys other than Id Parameter name: splitOn
Suggestions would be great.
The examples in the Test.cs are not what the code asks for as parameters for the queries. These need to be updated
for me this works perfect ... perhaps a typo?
I see PhyscialId which definitely looks like one.
class Company
{
public int Id { get; set; }
public string Name { get; set; }
public Mailing Mailing { get; set; }
public Physical Physical { get; set; }
}
class Mailing
{
public int MailingId { get; set; }
public string Name { get; set; }
}
class Physical
{
public int PhysicalId { get; set; }
public string Name { get; set; }
}
public void TestSOQuestion()
{
string sql = #"select 1 as Id, 'hi' as Name, 1 as MailingId,
'bob' as Name, 2 as PhysicalId, 'bill' as Name";
var item = connection.Query<Company, Mailing, Physical, Company>(sql,
(org, mail, phy) =>
{
org.Mailing = mail;
org.Physical = phy;
return org;
},
splitOn: "MailingId,PhysicalId").First();
item.Mailing.Name.IsEqualTo("bob");
item.Physical.Name.IsEqualTo("bill");
}