I'm using the ASP.Membership provider and I've created an additional table for the user data. I'm only experimenting and I'm not worried about security or anything like that. I'm only concerned with the big picture.
I'm experimenting with Breeze, SPA, Entity Framework, and Web.API and perhaps I'm rushing in too fast before I'm getting a good grasp on the individual concepts.
My Breeze query looks like this:
[HttpGet]
public IQueryable<object> Users()
{
return (
from user in _contextProvider.Context.Users
join membership in _contextProvider.Context.Memberships on user.UserId equals membership.UserId
join userProfile in _contextProvider.Context.UserProfiles on user.UserId equals userProfile.UserId
select new { user, membership, userProfile}
);
}
My results looks like this (only first record shown):
{
$id: "1",
$type: "<>f__AnonymousType4`3[[SPA01.EntityFramework.User, SPA01],[SPA01.EntityFramework.Membership, SPA01],[SPA01.EntityFramework.UserProfile, SPA01]], SPA01",
user: {
$id: "2",
$type: "SPA01.EntityFramework.User, SPA01",
UserId: "dd59fcd1-9d88-4494-a37c-1c25155cb77d",
ApplicationId: "23042eba-1113-4e56-8ac6-4640120ecc6c",
UserName: "DHaworth",
IsAnonymous: false,
LastActivityDate: "2014-02-17T00:01:39.707",
Membership: {
$id: "3",
$type: "SPA01.EntityFramework.Membership, SPA01",
UserId: "dd59fcd1-9d88-4494-a37c-1c25155cb77d",
ApplicationId: "23042eba-1113-4e56-8ac6-4640120ecc6c",
Password: "sdfasdfsadfsadfsafasfae0dfzT64vo=",
PasswordFormat: 1,
PasswordSalt: "/CRUMPNf9+byEdPraeasfsaQJw==",
Email: "MyEmail#hotmail.com",
PasswordQuestion: "TR",
PasswordAnswer: "B4HOezQ/TYasdfasfasfgjz4oAOERhnc=",
IsApproved: true,
IsLockedOut: false,
CreateDate: "2014-01-04T05:18:18.063",
LastLoginDate: "2014-02-17T00:01:39.707",
LastPasswordChangedDate: "2014-01-12T21:58:30.497",
LastLockoutDate: "1754-01-01T00:00:00.000",
FailedPasswordAttemptCount: 0,
FailedPasswordAttemptWindowStart: "1754-01-01T00:00:00.000",
FailedPasswordAnswerAttemptCount: 0,
FailedPasswordAnswerAttemptWindowsStart: "1754-01-01T00:00:00.000",
Comment: null,
User: {
$ref: "2"
}
},
UserProfile: {
$id: "4",
$type: "SPA01.EntityFramework.UserProfile, SPA01",
UserId: "dd59fcd1-9d88-4494-a37c-1c25155cb77d",
FirstName: "Duane",
LastName: "Haworth",
User: {
$ref: "2"
}
},
Roles: [ ]
},
membership: {
$ref: "3"
},
userProfile: {
$ref: "4"
}
},
I'm creating a User Admin screen where I'm going to display the information from all three tables.
Can I do this while still using Breeze using JsonResultsAdapter or do I need to do something on the Entity Framework side first?
Thanks
Breeze supports this scenario (wrapping entities in an anonymous object) out of the box; no extra work required. See the lookup lists example, for instance. The Breeze client needs to have the metadata to handle the entities, but that's no problem if you're using EF and the EFContextProvider.
Related
I've been struggling for some days now and feel dumb. I'm new to GraphQL and Prisma.
I'm creating a simple CRUD app with Next.js, GraphQL-Yoga, Prisma, Pothos, Apollo-Client and auth0. I use supabase for a PostgreSQL database. I want to query the posts and the corresponding user for each post. So I can map over it in react and display for example the role and the email of each user next to their post. I made a many-to-many relationship in the schema.prisma.
I tried using a one-to-many relation but I could only get, for example, the id, not the id and the email simultaneously.
GraphQL-Playground query:
query MyQuery {
posts {
title
id
user {
email
id
}
}
}
The user remains empty. Output:
{
"data": {
"posts": [
{
"title": "Lettuce",
"id": "1",
"user": []
},
{
"title": "Banana",
"id": "2",
"user": []
},
{
"title": "Carrot",
"id": "3",
"user": []
}
]
}
}
// /prisma/schema.prisma:
model User {
id String #id #default(uuid())
createdAt DateTime #default(now())
updatedAt DateTime #updatedAt
email String? #unique
image String?
role Role #default(USER)
Posts Post[]
}
model Post {
id String #id #default(uuid())
createdAt DateTime #default(now())
updatedAt DateTime #updatedAt
title String
description String
category String
User User[]
}
// /graphQL/types/Post.ts
import { builder } from "../builder";
builder.prismaObject("Post", {
fields: (t) => ({
id: t.exposeID("id"),
title: t.exposeString("title"),
description: t.exposeString("description"),
category: t.exposeString("category"),
user: t.relation("User"),
}),
});
builder.queryField("posts", (t) =>
t.prismaField({
type: ["Post"],
resolve: (query, _parent, _args, _ctx, _info) =>
prisma.post.findMany({
...query,
}),
})
);
It seems like this is what I need but when I integrate the <builder.queryType> portion I get an error saying:
PothosSchemaError: Duplicate typename: Another type with name Query already exists.
I tried some other things and got nothing. It seems like REST is so much easier.
I am using Redux + Redux-thunk to fetch datas from my API.
The data returned by my thunk is an array that looks like this :
[
{id_user: 1, name: "Joe", surname: "M", email: "joe#email.fr"},
{id_user: 2, name: "Jimmy", surname: "S", email: "jimmy#email.fr"},
{id_user: 9, name: "Jhonny", surname: "H", email: "jhonny#email.fr}
]
What I would like to do but don't get how to, is to store this data in my global state using the index storage pattern.
For exemple, from the fetched array showed above, the data structure I would like to store would look like this :
{
"usersById": {
1: {
id_user: 1,
name: "Joe",
surname: "M",
email: "joe#email.fr"
},
2: {
id_user: 2,
name: "Jimmy",
surname: "S",
email: "jimmy#email.fr"
},
9: {
id_user: 9,
name: "Jhonny",
surname: "H",
email: "jhonny#email.fr
}
}
}
Here is how I tried doing it in my success user fetch action creator :
export const fetchUsersSuccess = (users) => ({
type: types.FETCH_USERS_SUCCESS,
users: users.map(user =>
'userById': {
[user.id_user]: {
id_user: user.id_user,
name: user.name,
surname: user.surname,
email: user.email,
}
}
}),
loading: false,
});
The problem is, this still returns an array, looking like this :
[
userById: {
1: {
id_user: 1
name: "Joe"
surname: "M"
}
},
userById: {
2: {
id_user: 2
name: "Jimmy"
surname: "S"
}
},
userById: {
9: {
id_user: 9,
name: "Jhonny",
surname: "H"
}
},
]
I searched around but could not get an answer for this. I also tried to format the fetched data from the fetching thunk directly but I think this is not the solution ? Am I wrong ?
Or maybe this logic should go to the reducer ?
I know this must be simple stuff but I can't get over it, making me trying over-complicated things for, I guess, something as simple as this.
Any help would be greatly appreciated. Thank you very much
Our official Redux Toolkit package specifically has a createEntityAdapter API that implements managing data in a normalized form in the store.
For examples of how to use it, see the "Redux Essentials" core docs tutorial, Part 6: Performance and Normalizing Data, and the "Managing Normalized Data" section in the Redux Toolkit Usage Guide.
I am doing this in Flutter, with a Firebase database, using the Firestore packages in Flutter. I would like to know how a join is done in noSQL (or more specifically, in Flutter-Firestore)
This is what my database looks like:
users: {
U1: {
name: 'Peter',
surname: 'Jensen'
},
U2: {
name: 'Marry',
surname: 'Kown'
},
...
}
groups: {
G1: {
name: 'Group 1'
},
G2: {
name: 'Group 2'
},
...
}
members: {
M1: {
userId: U1,
groupId: G1
},
M2: {
userId: U1,
groupId: G2
},
M3: {
userId: U2,
groupId: G1
},
...
}
Now how do I do a join to get something like this:
members: {
M1: {
userId: {
name: 'Peter',
surname: 'Jensen'
},
groupId: {
name: 'Group 1'
}
},
M2: {
userId: {
name: 'Peter',
surname: 'Jensen'
},
groupId: {
name: 'Group 2'
}
},
M3: {
userId: {
name: 'Marry',
surname: 'Kown'
},
groupId: {
name: 'Group 1'
}
},
...
}
Do I do:
const users = await Firestore.instance.collection('users').getDocuments();
const groups = await Firestore.instance.collection('groups').getDocuments();
const members = await Firestore.instance.collection('members').getDocuments();
...manually loop through everything and assign everything myself
(I need to add more text because I have 'mostly code'): I would assume the above would use of a lot of query data in Firebase, so I can't see how this would be a good idea. I actually just want to see in what groups is a user a in
If you have groups and members, I'd typically store the follow data:
A list of users in a users collection.
For each user I'd keep their properties and a list of the group IDs of the groups they're a member of.
A list of groups in a groups collection.
For each group I'd keep their properties
Note that you could model the nested list as a subcollection, but typically this is not needed. With the above model you can easily find what groups a user is part of, even even do a query for users who are part of a certain group with an array-contains clause.
To get a list of the properties of the group for a specific user, you'll indeed need to load that user, and their groups separately. This is normal with many NoSQL databases, and not necessarily as slow as you may expect. But if performance is not good enough, you can consider duplicating some data to reduce the need for joins. It all depends on your needs, and unlike in relational data models, NoSQL is not dogmatic about such things.
To learn more about this topic:
read NoSQL data modeling
watch Getting to know Cloud Firestore
I have a CosmosDB setup using the Mongo API. I have a collection with a hashed shard on one of the field of the document. When I run commands like db.collection.remove or db.collection.deleteMany I get the following error.
Command deleteMany failed: query in command must target a single shard key.: {"message":"Command deleteMany failed: query in command must target a single shard key."}
I'm not sure how can I mention a shard key as part of the query considering I want the query to run across all the shards.
You need to provide shard key when you want to run commands like db.collection.remove or db.collection.deleteMany.
For example :
My data source as below:
[
{
"id" : "2",
"name" : "b"
},
{
"id" : "1",
"name" : "a"
}
]
And my shared key is "/name". Use db.coll.deleteMany({"name":"a"}) to delete specific shard.
Hope it helps you.
It should be ShardKey which you have chosen when you created cosmosDb collection.
FilterDefinition<Product> filter = Builders<Product>.Filter.Eq("id", 2);
=== 2 is my shardKey
await this._dbContext.GetProducts.DeleteOneAsync(filter);
return RedirectToAction("Index");
Kindly refer an image below , how does it look like in CosmosDB
Shard Key(Partition Key) has to be provided during specification of schema model in the code. Once its provided, we can perform regular operation like save, update and delete as usual.
Example:
const mySchema = new Schema({
requestId: { type: String, required: true },
data: String,
documents: [{ docId: String, name: String, attachedBy: String }],
updatedBy: {
type: {
name: { type: String, required: true },
email: { type: String, required: true },
}, required: true
},
createdDate: { type: Date, required: true },
updatedDate: { type: Date },
}, { shardKey: { requestId: 1 } }
);
In the above code we specified requestId as Shard Key, now we can perform any mongo operations
Example:
let request:any = await myModel.findById(requestId);
request.data ="New Data";
await request.save();
Hope that helps.
This works with all Mongo operations
I'm currently trying to add new users to Firebase via the AngularFire $set() method. I'm creating new users via the $createUser method from AngularFire. My code looks like this:
$scope.createUser = function() {
$scope.auth.$createUser('dolly#gmail.com', 'password').then(function(user, err) {
if (err) {
console.log('ERROR: ' + err);
} else {
sync.$set('users', user);
}
});
}
This is a creating new user and placing the new user object inside of users:{..}, however, it is also adding an additional user child object thats just duplicate data -- this is what the code is adding to Firebase:
{
"users": {
"email": "dolly#gmail.com",
"id": "11",
"isTemporaryPassword": false,
"md5_hash": "xxxxxxxxxxxxxxx",
"provider": "password",
"sessionKey": "xxxxxxxxxxxxx",
"token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiOjE0MDc5NDQ2NDYsInYiOjAsImQiOnsicHJvdmlkZXIiOiJwYXNzd29yZCIsImlkIjoiMTEiLCJ1aWQiOiJzaW1wbGVsb2dpbjoxMSIsImVtYWlsIjoiZG9sbHlAZ21haWwuY29tIiwibWQ1X2hhc2giOiIzsdrggfeedsaadrfcDc0ZDRhMTU5NTk2NzI1NzFmMDk2ZTZlNyIsImlzVGVtcG9yYXJ5UGFzc3dvcmQiOmZhbHNlLCJzZXNzaW9uS2V5IjoiM2MwMDNjODkxMDEzOWE5MjhlZTZjNWI1NjU5ZTRiZjMifSwiaWF0IjoxNDA3ODU4MjQ2fQ.p7-9GDtaNpBn1ICTLIUSwlPytaUGi-jyBgcO-LKHUys",
"uid": "simplelogin:11",
"user": {
"email": "dolly#gmail.com",
"id": "11",
"isTemporaryPassword": false,
"md5_hash": "xxxxxxxxxxxxxxx",
"provider": "dfrggrssxxxxxxx",
"sessionKey": "xxxxxxxxxxxxxxx",
"uid": "simplelogin:11"
}
}
I ideally want my users object to look like the example in firebase, except with each user key to be whatever is inside user.uid
users: {
user1: {
name: "Alice"
},
user2: {
name: "Bob"
}
}
Where each new user will be added to the users: {...} key without the duplicate user child tacked on?
If you create a reference to users/ and then call $set on that path, then whatever data you include will replace anything at that path. This is AngularFire 101. You should begin by reading at least that section if not the entire guide.
Choose the path you want to set data at when creating your sync object.
var ref = new Firebase('.../users/'+user.uid);
var sync = $firebase(ref);
sync.$set({ email: user.email, provider: user.provider });
Or, better yet, just set it on the reference since you aren't utilizing this for client-side bindings.
var ref = new Firebase('.../users/'+user.uid);
ref.set({ email: user.email, provider: user.provider });
Creating profiles is explained in the Firebase docs and covered in the AngularFire-Seed repo's createProfile service, nearly verbatim to your example.