I've got a GET entry point on UsersController. But this one is responding an array of empty objects. When I debug the entry point, the list (IEnumerable<UserViewModel>) is not empty and UserViewModels are not empty either.
But here is what it does respond:
[{},{},{},{},{},{},{},{},{},{},{},{}]
And the controller code:
[HttpGet]
public async Task<IEnumerable<UserViewModel>> Get()
{
var u = _stObjMap.Default.Obtain<UserTable>();
using (var ctx = new SqlStandardCallContext())
{
var a = await ctx[u].Connection.QueryAsync<UserViewModel>("SELECT UserId, UserName, PrimaryEMail, CreationDate from CK.vUser where UserId <> 0 and UserId <> 1");
return a;
}
}
I really don't think that the problem is coming from the controller.
I'm using Dapper.I really don't know what is happening. And I have to write a lot because I can't edit this post
Most likely the UserViewModel has no public properties defined.
Which is why no key value pairs are displayed when the object is serialized to JSON.
Based on the query, make sure there are matching properties in the model for the Dapper query to map the selected columns
public class UserViewModel
public int UserId { get; set; }
public string UserName { get; set; }
public string PrimaryEMail { get; set; }
public DateTime CreationDate { get; set; }
}
Related
Fairly new to EF.Core and I'm having some issues as my tables start getting more complex. Here's an example of what I have defined for my classes. Note ... there are many more columns and tables than what I have defined below. I've paired them down for brevity.
public class User
{
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public bool Active { get; set; }
}
Followed by
public class JournalEntry
{
public int Id { get; set; }
public int UserId { get; set; }
public string Details { get; set; }
public DateTime DateEntered { get; set; }
public virtual User User { get; set; }
}
I want to be able to issue the following query and INCLUDE the User Table so that I can then populate a ViewModel with columns from the User Table without having to do another lookup and also to sort the data while retrieving it:
public IQueryable<JournalEntry> GetByUser(int userId)
{
return _DbContext.JournalEntries.Where(j => j.UserId == userId)
.Include(u => u.User)
.OrderBy(u=> u.User.FirstName)
.ThenBy(j => j.DateEntered);
}
My controller would then have something similar to the following:
public IActionResult List(int userId)
{
var journalEntries = new _dbRepository.GetByUser(userId);
var myViewModel = new MyViewModel();
myViewModel.UserName = ($"{journalEntries.User.FirstName} {journalEntries.User.LastName}");
myViewModel.Entries = journalEntries;
etc ....
return View(myViewModel);
}
I'm loading the user's first and last name in the View Model and whatever other attributes from the various tables that are referenced. The problem that I'm having is that I'm getting errors on the Migration creation "Foreign key constraint may cause cycle or multiple cascade paths." And of course, if I remove the line reading public virtual User User { get; set; } from the JournalEntry class then the problem goes away (as one would expect).
I believe that the way I'm doing the models is incorrect. What would be the recommended way that I should code these models? I've heard of "lazy loading". Is that what I should be moving towards?
Thanks a bunch.
--- Val
Your query returns an IQueryable<JournalEntry> not a JournalEntry.
Change the code to get the user details from the first object:
var myViewModel.UserName = ($"{journalEntries.First().User.FirstName} {journalEntries.First().User.LastName}");
In the line above I'm calling First() on your journal entries collection and that would have a User. Then I can access FirstName and LastName.
Also, don't bother with LazyLoading since you are learning. It could cause select n+1 issues if used incorrectly
So I'm trying to store a record in the databse using dapper. I'm passing an object to the method where I have my query to store the recorde. Let me be more clear. Below is my model :
public class Foo
{
public long FooId { get; set; }
public Guid Foo2ID { get; set; }
public string Status { get; set; }
public Person Person { get; set; } = new Person();
}
public class Person
{
public string Type { get; set; }
public string Character { get; set; }
public DateTime Test { get; set; }
}
And this is my query :
public async Task<ActionResult> Create(Foo f)
{
using (var connection = _dbAccess.CreateConnection())
{
var sqlStatement = #"
INSERT INTO ReportRequests
(FooId
,Foo2Id
,Person
,Status)
VALUES
(#FooId
#,Foo2Id
#,Person
#,Status)";
await connection.ExecuteAsync(sqlStatement, f);
};
return Ok();
}
I'm trying to save a json in the Person column in the database. But I get this error :
The member x of type x cannot be used as a parameter value
Can anyone please give me an idea on how I can approach to this problem. It would be very helpful.
Thank you a lot :)
enter code hereFirst of all, you should consider whether you can use LINQ-like queries with dapper. It makes it both more readable and avoids having issues like that.
Back to your problem, from the code you posted it looks like you've misplaced the comas after the # symbol #,Foo2Id :
(#FooId
#,Foo2Id
#,Person
#,Status)
It should be:
(#FooId
#Foo2Id,
#Person,
#Status)
In our app we have a user model linked to a mongoDB database. My question is about modifying only a value from key/value pair inside a given user data (of course using the User ID).
Here is my simple model:
public class User
{
[BsonId]
public string Id { get; set; }
public string email { get; set; } = string.Empty;
public bool hasAcceptedTerms { get; set; } = false;
public int state { get; set; } = 0;
public int UserId { get; set; } = 0;
public IList<UserFile> SubmittedFiles { get; set; }
}
public class UserFile
{
public int fileID { get; set; }
public bool hasFile { get; set; }
}
On our app, after authenticate the user for the first time, we create his entry in the Mongo Database using
public async Task AddUser(User item)
{
await _context.Users.InsertOneAsync(item);
}
After his first login we want to update the fact he accepted Terms: by doing so we want to change hasAcceptedTerms to true and move the state key from 0 to 1.
For the moment in our Repository we have something like:
public async Task<UpdateResult> UpdateUser(string id, User item)
{
return await _context.Users
.ReplaceOneAsync(n => n.Id.Equals(id)
, item
, new UpdateOptions { IsUpsert = true });
}
But by doing so we must provide a full item corresponding to our model.
I don't find any way to create a function which I could use like:
UdateUserData(string id, string data, bool newvalue);
For example call UpdateUserData('user1objectidhash', 'hasAcceptedTerms', true) would modify the correct value for the user identified by his ObjectID Id.
First problem: is typing data as string a good idea/unique solution? I don't find my function call being elegant by typing the data key as a string.
2nd: I don't know what will be the type of newvalue because it will depend on what is the data I want to modify. Can I detect it from model?
3rd: I don't know the correct Mongo.Driver function which can process this update.
Could you give me some cues and tips?
If you just want to update not whole object, but some properties it's possible to do this Update command:
collection.UpdateOneAsync(x=>x.Id ==id,
Builders<User>.Update.Set(u=>u.hasAcceptedTerms, false)
.Set(u=>u.state, 1));
I assume, that collection is your IMongoCollection<User> , that you mean with _context.Users
I have a method that is reading a serialized string from my database and then attempting to de serialize it while passing it into my model, for the purposes of this, i will hard code the data in, it is giving me the same result both ways
const string serialized =
"{\"Id:\": 1,\"Title:\":\"Mr\" ,\"Name:\":\"Someone Random\",\"Dob:\":\"2016-02-20 00:00:00.000\",\"Address:\":\"Just around the corner\",\"Email:\":\"somone.random#email.com\",\"Telephone:\":\"000022233441\",\"Mobile:\":\"079999999\"}";
using (var sr = new StringReader(serialized))
{
using (var jr = new JsonTextReader(sr))
{
var js = new JsonSerializer();
var model = js.Deserialize<DataWrapper>(jr);
return model;
}
}
My DataWrapper model looks like so
public class DataWrapper
{
public int Id { get; set; }
public string Title { get; set; }
public string Name { get; set; }
public DateTime Dob { get; set; }
public string Address { get; set; }
public string Email { get; set; }
public string Telephone { get; set; }
public string Mobile { get; set; }
}
Now no matter if I am hard coding the data in or returning it from the database, it always returns a blank Model
at the point where i am trying to Deserialize the data into my model, the data is actually there(in the jr) but it seems it is being lost at the same time, so when i return my model, it is always a blank instance of my model
Any help would be much appreciated
Within your JSON string, you've added a ':' at the end of your property names. Pretty-printed, your JSON looks like this:
{
"Id:": 1,
"Title:": "Mr",
etc.
}
To automatically map to your properties, remove the trailing colon, i.e.:
{
"Id": 1,
"Title": "Mr",
etc.
}
You wrote ":" character at the end of properties. Remove them and let them to be like that:
"{\"Id\":2,\"Title\":\"aaa\",\"Name\":null,\"Dob\":\"0001-01-01T00:00:00\",\"Address\":\"sdfsd\",\"Email\":null,\"Telephone\":null,\"Mobile\":null}";
I am getting a simple object from a form in a MVC4 application
portfolio = {code: xxxxx, quantity: -10}
I need to add the Username to the database when I do this insert which I already know I can get from the HTTPContext.
What would be the best way to include this in the below code. I know I will need to change the object I am adding but what is the right way to do this?
public ActionResult Add(Portfolio portfolio)
{
var ctx = new MarginEntities();
ctx.Portfolios.Add(portfolio);
ctx.SaveChanges();
return RedirectToAction("Index");
}
Extend the Portfolio class to include the necessary property:
class Portfolio
{
public string Code { get; set; }
public int Quantity { get; set; }
public string Username { get; set; }
}
When the request comes from client, fields Code and Quantity are initialized, and Username is set to its default value, which is null. So simply initialize it before submitting to DB:
public ActionResult Add(Portfolio portfolio)
{
portfolio.Username = Session["Username"]; // or however the username is stored
var ctx = new MarginEntities();
ctx.Portfolios.Add(portfolio);
ctx.SaveChanges();
return RedirectToAction("Index");
}
You could use the User object, I take it all users are first authenticated?
User.Identity.Name
Your Portfolio object could then either have a string for the username or you could use a FK to the 'users' table, and get this ID by passing in the Name property from above.
You could then have either:
class Portfolio
{
...
public string Username { get; set; }
}
If you take this approach, then you would just pass the Portfolio object with the new Username property set.
or
class Portfolio
{
...
public int UserId { get; set; }
}
if you take this approach then you would need to request the UserId from EF context and then populate the Portfolio object with the returned UserId