So i'm trying to set up my first extension with Typo3 and i'm struggling very much. I want to set up an extension which handles reclamations from customers.
After submitting the input values i'll store the new customer in the database and directly after this step i'll get it back from the database to see which uid he has, to store the uid from the customer in the reclamation.
So i wan't to override the current $customer-variable with
$customer = $this->customerRepository->findByName($name);
The returned result is not really an object of customer even var_dump is saying it is an customer-object. I can't call the function
$customer->getUid()
to get the current uid of this new customer. But i need the uid of the customer in my reclamation-object - how do i do that?
Next problem: every query i ll do to the db like
->findAll(), findByIdentifier($identifier)
is null.
I don't know why. It seems that he can't find the storagePid, but i've set up my TypoScript correctly.
I can only get a query when i add
$query->getQuerySettings()->setRespectStoragePage(FALSE);
any ideas where the dog is buried in this case?
Thank you very much and sorry for my bad english :P
Your initial question is hard to answer without more details. What is the relation between a customer and reclamations? If a customer can have multiple reclamations, it would be good to have an 1:n relation between customer and reclamations. In that case, you can just do $customer->addReclamation($reclamation) and don't need to take care about user UIDs.
As for your repository call, the problem is that your call gets you a QueryResult containing all matching objects. If name is really a unique property, you can do
$customer = $this->customerRepository->findOneByName($name);
This looks for all customers with name equals $name (which should be only one) and returns the first one, so you get back a Customer object.
But this is not really necessary, too: If you persist all changes after adding the customer, you can get its UID:
$this->customerRepository->add($customer);
$this->persistenceManager->persistAll();
// Returns the customer uid
$customerUid = $customer->getUid();
The persistenceManager can be injected like this:
/**
* #var \TYPO3\CMS\Extbase\Persistence\Generic\PersistenceManager
* #inject
*/
protected $persistenceManager;
Related
I have a two aggregate roots in my domain, and therefore two repositories. We'll call them BookRepository, and AuthorRepository, for the sake of example.
I'm designing an MVC application, and one page has to display a table containing a list of authors, with each row showing the author's personal details. At the end of each row is a small button that can be clicked to expand the row and show a child table detailing the author's published books.
When the page loads, some ajax is executed to retrieve the Author details from an API controller and display the data in the table. Each property in an Author object maps almost directly to a column, with one exception, and this is where I'm having my problem. I want the button at the end of each row to be disabled, if and only if the author has no published books. This means that a boolean has to returned with each Author record, indicating if they have any published books.
My book repository has a couple of methods like this:
public IEnumerable<Book> GetBooksForAuthor(int authorId);
public bool AnyBooksForAuthor(int authorId);
and my Book class has a property called AuthorId, so I can retrieve a book's author by calling
authorRepository.GetById(book.AuthorId);
My problem is that in order to create a row for my aforementioned table, I need to create it like this:
IEnumerable<Author> authors = authorRepository.GetAll();
foreach (Author author in authors)
{
yield return new AuthorTableRow
{
Name = author.Name,
Age = author.Age,
Location = author.PlaceOfResidence.Name,
HasBooks = this.bookRepository.AnyBooksForAuthor(author.Id)
};
}
The above code seems correct, but there's a fairly heft performance penalty in calling this.bookRepository.AnyBooksForAuthor(author.Id) for every single author, because it performs a database call each time.
Ideally, I suppose I would want an AuthorTableRowRepository which could perform something like the following:
public IEnumerable<AuthorTableRow> GetAll()
{
return from a in this.dbContext.Authors
select new AuthorTableRow
{
Name = a.Name,
Age = a.Age,
Location a.PlaceOfResidence.Name
HasBooks = a.Books.Any()
});
}
I'm hesitant to put this in place for these reasons :
AuthorTableRowRepository is a repository of AuthorTableRows, but AuthorTable row is not a domain object, nor an aggregate root, and therefore should not have its own repository.
As Author and Book are both aggregate roots, I removed the "Books" property from the Author entity, because I wanted the only way to retrieve books to be via the BookRepository. This makes HasBooks = a.Books.Any() impossible. I am unsure whether I am imposing my own misguided best practice here though. It seems wrong to obtain Books by obtaining an Author via the AuthorRepository and then going through its Books property, and vice versa in obtaining an Author via a property on a Book object. Crossing aggregate root boundaries would be the way I'd term it, I suppose?
How would other people solve this? Are my concerns unfounded? I am mostly concerned about the (what should be a) performance hit in the first method, but I want to adhere to best practice with the Repository pattern and DDD.
I would stick to the first approach, but try to optimize things in the bookrepository method. For instance, you can load this information all in one time, and use in-memory lookup to speed this up. Like this you would need 2 queries, and not 1 for each author.
The way I solved this in the end was to create an Entity from a view in the database. I named the entity 'AuthorSummary', and made an AuthorSummaryRepository that didn't contain any Add() methods, just retrieval methods.
I have a Customer table and another Orders table. Each Customer can have many orders (One to many relationship).
I want to get a Customer object and from it get how many orders he has (the actual order data is not relevant at this point). So as I see it I have 2 options:
create a view with another OrdersCount field - and that will be another object in my system.
in my app, when I need the count get the Customer.Orders.Count - but for my understanding that will cause an extra query to run and pull all the orders from the database to that collection.
Is there a correct way to do such thing?
Thanks
You do need a new type, but you don't need to recreate all relevant properties.
from c in context.Customers
// where ...
select new {
Customer = c,
OrderCount = c.Orders.Count()
}
Update code that looks for e.g. the Name property of an item in the result, to look for Customer.Name.
I have a form which has several unique fields for that form say, School, class,
Location etc and several fields that needs to be repeated say, , Student id, Student name, Student roll no.
I want to repeat the last three fields 10 times.
Secondly, how do I store it in database (MySQL using doctrine). I mean rows should be created depending on the number of last three fields and the first three fields should remain same.
How do I achieve this in a Symfony2?
Any help will be highly appreciated.
The form structure is something like this:
School Class Location
Sno Student id Student Name Student Roll No
1.2.3.4.5.And so on......Edit: Fixed at 10 rows
Update
Entity Class:
class StudentForm
{
private $id;
private $school;
private $class;
private $location;
private $id;
private $name;
private $rollNo;
getter/setter methods follow
Well. Up to now I always used the JavaScript provided in the example. You could try to call this function 10 times, or see how the markup is created. But then again this will probably not work with the code in the controller from the example.
You can always create the whole markup yourself and then just see who that data is received in your controller. But then again, there wasn't too much information in your initial description. It seemed you currently don't have the code for your entities.
After a good long process of trial and error, I finally managed to do it.
The doctrine documentation helped creating a collection (though it didn't give enough information on saving the objects) for the repeating rows and so did the inputs of #Dirk Olbertz here. Thank you.
What is the best practise for updating a single field for one record (with specific ID) using ADO.Entity?
As far as I know, you have to retrieve the whole object by id, update the property and call SaveChanges:
int id = ...;
var db = new MyEntities();
var o = (from mo in db.myObject
where mo.id = idObject
select mo).First();
o.MyProperty = "some value";
db.SaveChanges();
But it seems a little bit overhead having to retrieve the whole object, since I don't care for the values of the record because I just want to set a property, regardless of the values.
Another option would be to create a stored procedure for this purpose...
Re: What is the best practise for updating a single field for one record (with specific ID) using ADO.Entity?
Answer: Best practice is to retrieve the entire record, update one or more fields, and then store the record. -- Just as you're doing.
I was wondering with Entity Framework 4.1 code first how do you guys handle queries that involve an existing aspnet_Users table?
Basically I have a requirement for a query that involves the aspnet_Users so that I can return the username:
SELECT t.Prop1, u.Username
FROM Table1 t
INNER JOIN aspnet_User u ON t.UserId = u.UserId
Where t.Prop2 = true
Ideally in linq I would like:
from t in context.Table1
join u in context.aspnet_Users on t.UserId equals u.UserId
where t.Prop2 = true
But I'm not sure how to get aspnet_Users mapping to a class User? how do I make aspnet_Users part of my dbset ?
Any help would be appreciated, thanks in advance
Don't map aspnet_Users table or any other table related to aspnet. These tables have their own data access and their own logic for accessing. Mapping these tables will introduce code duplication, possible problems and breaks separation of concerns. If you need users for queries, create view with only needed information like id, user name, email and map the view. The point is that view will be read only, it will contain only allowed data and your application will not accidentally modify these data without using ASP.NET API.
First read Ladislav's answer. If you still want to go ahead : to do what you want would involve mapping the users and roles and members tables into the codefirst domain - which means writing a membership provider in code-first.
Luckily there is a project for that http://codefirstmembership.codeplex.com/ although its not a perfect implementation. The original is VB, look in the Discussion tab for my work on getting it running in c# MVC.
I'm working with the author on a better implementation that protects the membership data (password, last logged on date, all of the non-allowed data) but allow you to map and extend the user table. But its not ready yet!
You don't really need to use Entity Framework to access aspnet_membership provider accounts. You really just need to create an instance of the membership object, pass in a unique user identifier and a Boolean value indicating whether to update the LastActivityDate value for the user and the method returns a MembershipUser object populated with current values from the data source for the specified user.
You can then access the username by using the property of "Username".
Example:
private MembershipUser user =
Membership.GetUser(7578ec40-9e91-4458-b3d6-0a69dee82c6e, True);
Response.Write(user.UserName);
In case you have additional questions about MembershipProvider, you can read up on it on the MSDN website under the title of "Managing Users by Using Membership".
Hope this helps you some with your requirement.