Right way to model relationship in Entity Framework Core - asp.net-core

I'm working on an ASP.Net Core MVC 2.0 application using Entity Framework Core 2.0. I need to upload a file related to an entity that is getting created by this application.
For example, imagine having to upload an invoice PDF as part of creating a payment entity. This should be a one-to-one relationship.
I'm having some trouble deciding how this should be represented in the Entity Framework data (and object) model. I found some guidelines that say that the entity foreign key should exist on the dependent object. In this case, the invoice would be the dependent object, so I should add the payment ID to the invoice object.
But I won't be downloading the invoice object as often as I would the payment object. And I was planning on a flow where the payment view would have a link to an action on the invoice controller to download the invoice using the invoice ID. So having the Invoice ID on the Payment object would make sense.
So I'm not sure of the best way to handle this.
As an aside, I've seen plenty of samples with uploading/downloading files, but not many that shows them how this might look when the files are associated with an entity in the database.
Does anyone have any suggestions?
I don't have any code that I can share at the moment; if anyone thinks code might help, I can throw something together.
Thanks in advance!

Just wanted to point out that Gert Arnold's comment was the correct answer; the following has examples of how to model one-to-one relationships.
https://learn.microsoft.com/en-us/ef/core/modeling/relationships
Thanks Gert!

Related

Asp.Net Core REST API Hierarchical data structure

I have a question regarding how to structure my controllers.
Let's assume I have a have a system that has stores and products and stores have products.
so the way to get stores is /api/stores/{id} and the way to get a product is /api/product/{id} or /api/stores/{id}/product/{id}.
How would you structure the Controllers? should I have a controller for products and controller for stores and every route that starts with stores in it should reside in StoresController otherwise in ProductsController?
This is from Microsoft: Api design guidance
In more complex systems, it can be tempting to provide URIs that enable a client to navigate through several levels of relationships, such as /customers/1/orders/99/products. However, this level of complexity can be difficult to maintain and is inflexible if the relationships between resources change in the future. Instead, try to keep URIs relatively simple. Once an application has a reference to a resource, it should be possible to use this reference to find items related to that resource. The preceding query can be replaced with the URI /customers/1/orders to find all the orders for customer 1, and then /orders/99/products to find the products in this order.

Zend Framework 2 - Importer for multiple Rest or Soap Apis

I want my ZF2 Application to import data from many different REST or SOAP Services, which may use different authentication types and so on.
Now I'm basically looking for a structure / architecture how to implement this, maybe some design patterns or ready to use modules if they exist.
Every information could help. I'm also thankful for API docs or tutorials that you provide.
But my main question is: How should be the structure for this kind of "importer"
My Application:
Based on Zend Skeleton Application
Using Doctrine 2
Trying to use all ZF2 Best Practices I can find
Consists of many modules, entities and complex associations in some cases
Entities that I want to import are already working (crud operations, validation, ...)
Apis that I want to use:
Usually E-Commerce stuff, like products, orders, stock keeping
Magento Api (Thinking of Rest)
Shopware and other important Webshops
Ebay Stores
Amazon (I think is going to be the hardest one)
Must have functionality:
I want the api URLs and authentication data to be configurable in my app with doctrine entities
The "Api" Entity should be associated to my "Shop" Entity. Orders or Products that I import or create directly in my App are also associated to my Shop entities. So every Shop/Ebay-Store/Amazon-Store is a "Shop" in my Application. This is already the part I've done.
For example product import should be done directly from my app frontend, I'm thinking of retrieving the api data first and then import them incremtally / step for step
I don't want fat controllers that transform the data into doctrine entities and save them one by one. This way complex associations would become very hard to maintain.
Need a good approach for data transformation and hydration to doctrine entities. Because the data I retrieve from api will usually not have the same structure as my entities. Maybe an attribute that's a property of the "Product" entity in foreign app is excluded into an associated entity in my own application.
Many modules in my application will have entities that should be importable from these apis, so I need a central component that does the job
How would be the best approach for this? I'm not asking for a complete solution, but ideas that fit these requirements.
The Zend HTTP client and its relatives (like Zend OAuth) provides most of the functionality that you need to implement fetching the data from the services.
You can then persist the response in any number of ways, but a schema-less database like Mongo DB makes saving dynamic data much easier. If you are stuck using a relational DB like MySQL then you can either setup an EAV database, or use dynamically generated tables.

WCF REST Resource Design - POSTing vs. GETing

I am designing a REST service for my company. No one here has had much experience with REST so I read through a few books on the subject but I am stuck on resource design of a POST vs. the resource design of a GET request for the same data. Particularly in the case of foreign relationships.
For instance I have a class PurchaseRequest which represents a request to purchase some fixed asset. Behind the scenes my service is an interface to a relational DB. There is a PURCHASE_REQUEST table which has a foreign key to an ASSET table (Defining which of a fixed list of assets are being requested) and a PERSON table (Defining which of the users is doing the requesting). Currently in my service when a GET command is issued for a purchase request, the service returns the whole thing: An XML representation of the PURCHASE_REQUEST table entry along with a list of asset entries like so:
<PurchaseRequest>
<ID></ID>
<RequestDate></RequestDate>
<Requestor href="/requestors/requestorID">
<RequestorID></RequestorID>
<FirstName></FirstName>
<LastName></LastName>
</Requestor>
<RequestedAssets>
<RequestedAsset href="/assets/AssetNumber" >
<AssetNumber></AssetNumber>
<Year></Year>
<Make></Make>
<Model></Model>
<Cost></Cost>
</RequestedAsset>
<RequestedAsset href="/assets/AssetNumber" >
<AssetNumber></AssetNumber>
<Year></Year>
<Make></Make>
<Model></Model>
<Cost></Cost>
</RequestedAsset>
<RequestedAsset href="/assets/AssetNumber" >
<AssetNumber></AssetNumber>
<Year></Year>
<Make></Make>
<Model></Model>
<Cost></Cost>
</RequestedAsset>
</RequestedAssets>
</PurchaseRequest>
This works pretty efficiently. The consuming application makes a single request and gets the whole thing and links to the full resource requestor resource or asset resource if they need them.
The problem comes on a POST. My gut tells me to try to use the same resource layout for POSTing a new purchase request as I used to retrieve an existing one. This is what all the examples in the books I have read do anyway. I don’t need to know anything more than the Asset Number and Requestor ID to fulfill the POST. That means that data is not necessary but the inefficiency alone is not what bothers me. The main thing is you should not be able to edit the year, make or model of an asset when creating a purchase request, those fields are pre-defined. You also should be able to create a new asset definition when creating a purchase request. Similarly you should not be able to update/create a person's details when creating a purchase request. There are separate services for creating/updating people and assets.
The only thing I can think of is to define a different DataContract class for the POST which has the minimum info to identify an asset or a person and does not expose those fields which cannot be updated. I really don’t love this option because it is going to create a large number of DataContracts classes (nearly all of the tables in my DB have foreign relationships, this is not isolated to one request or I would not be worrying about it) However I really don’t love my current design because REST does not have read-only fields.The burden is now on the consumers of my service to constantly be checking, "does it save this field… what about this one?..." Has anyone else ran into this issue? Is it common to have to define a separate DataContract class for POSTing and GETing? Seems like a pretty basic design question but I don’t see a lot of posts out there on the subject so I am hoping I just missed something. Any help is appreciated.

Embed Ektron smartform in another Ektron smartform

(Using Ektron version 8.6.1)
Say I have a smartform ContactInfo, something like:
<ContactInfo>
<Name></Name>
<Email></Email>
</ContactInfo>
I would like to create another smartform (e.g. NewsArticle) and "embed" ContactInfo inside
<NewsArticle>
<Title></Title>
<Summary></Summary>
...
<ContactInfo>
<Name></Name>
<Email></Email>
</ContactInfo>
</NewsArticle>
My solution thus far has been to include a Resource Selector field to add a reference to an existing smartform instance. I would prefer to make the association at the configuration level, to make the data entry workflow more intuitive.
I'm using Bill Cava's ContentTypes and generating classes from smartform XSDs, so it would also make the presentation code more natural and type-safe in that embedded fields could be accessed directly (rather than having to make another request based on a reference ID, which may or may not be an ID to the smartform I'm expecting).
I gather this is not possible out of the box; I'm not opposed to hacking Workarea code to make something like this work. Does anyone have experience with a scenario like this?
I heard from an Ektron rep that they are planning on elevating the role of smartforms in an upcoming summer release - can anyone offer some more info to that point? Perhaps smartform composition like I've described will be supported?
Currently it isn't possible to do smartform composition. Depending on why/if you actually need a second smartform definition, you could just define the contact info in the news article.
If the contact info smartforms are related to the news articles in a one to many or many to many fashion, then using the resource selector as you have is the only way that I know of to create the relationship you are looking for.
If the relationship is one-to-one or many-to-one, then I'd suggest doing away with the separate smartform definition.
If you can clarify the workflow you are trying to achieve for the content authors, I might be able to respond better.
The Content Types would represent the data in the CMS. Suppose, as in your example, a NewsArticle contains a reference to a ContactInfo. Embedding the ContactInfo inside your NewsArticle might make sense from a presentation perspective, but it turns your ContentTypes into a one-way data model. You would lose the ability to construct a new NewsArticle and persist it into the CMS.
What might work well for you is to leave the content types as-is, with the id of the ContactInfo from the resource selector. Then create a NewsArticleDisplayModel... essentially a view model that contains the news article data plus ContactName and ContactEmail.
Now, if you need the contact info to be searchable, you could get really fancy with CMS Extensions and hook into the OnBeforePublish event to update searchable metadata with the name from the ContactInfo, so that the NewsArticle can be searched for using the values from the other "embedded" resource. That could get kinda tricky, though... ideally you'd have to also hook into the publish events of the ContactInfo objects in case something changes on that side, too. Then do you create a custom database table to track which NewsArticle content ids are using a particular ContactInfo?
Your solution can get as complex as it needs to, but I would keep the content blocks separate. If nothing else, you'll end up with a more maintainable and upgradable solution.

Core Data - Multiple Entries for a Single Entity

So in my app I have an Entity called Cards and another called Transactions.
The Transaction entity have the attributes: Date, Location and Amount. So if a user spends his money in 10 locations, I need to have 10 entries in the Transactions for a single card.
I just started working with Core Data and it's getting messy.
I also use MagicalRecord to work with Core Data.
I was able to CRUD the cards entity, adding, updating etc... is all good.
The thing is, I need to add the transactions to a card and don't know how to start with this relationship. How to add transactions to the card and then fetch the card with all the transactions?
Any insight would be much appreciated.
If I understood you right, then you establish a relation between them.
Card -> Transaction is a To-Many relation. See the right hand pane in xcode for this option.
Add an inverse. Always add an inverse. So you have a not To-Many relation
Transaction -> Card
Right? There is only one card for each transaction?
The rest of the answer depends on how you access the data. I suggest to create a model class for each entity. You know how? Click on the entity then go to file/new/file, select core data then NSManagedObjectSubclass and it will be created for you. This class has methods for adding related items.
myTransaction.card = myCard;
respectively
[myCard addTransactionsObject:myTransaction];
Assuming of course that myCard and myTransaction are the classes and that your to-one relation is named card and the to-many relation is named transactions.
Just set a one-to-many relationship from Card to Transaction Entity, and then simply get all of your (previously added by [card addTransactionsObject:newTransaction] call) transactions using that relation: card.transactions.
Don't forget to add an inverse relation fromTransaction to Card!