I am using Azure mobile apps with .NET backend and Xamarin as client app.
I have multiple tables as follows:
Badges - where badge description is stored
Achievmentgroups - one group can have multiple badges .e.g badge x level 1 ,badge x level 2 , badge y level 1 ,badge y level 2... etc
CustomerAchievments - where the progress of each badge is stored for each user
Badges and achievmentsgroups are linked together with foreign key lets name it achievmentGroupId.
CustomerAchievments and Badges are linked together with foreign key lets name it BadgeId
In my client side, I would like to create one object from these three tables.
currently what I am doing is getting each table separately and i want to utilize object oriented programming more.
As of what I understand from your question The easiest way of doing this would be bunching them together so what your final class would look like is as shown below:
public class Customer
{
public Badges Badges { get; set; }
public Achievmentgroups Achievmentgroups { get; set; }
public CustomerAchievments CustomerAchievments { get; set; }
}
In this way, your .Net backend can send just one class and that can be used to get all your data individually!
a solution with an example here :
https://blogs.msdn.microsoft.com/azuremobile/2014/05/27/retrieving-data-from-1n-relationship-using-net-backend-azure-mobile-services/
Related
In my EF 6 Model First application, I have an entity with a many-to-many navigation property to another entity. In the first entity, I need to add several references to the same record in navigation property.
The first entity is a “saleslistItem” and the second entity is “warehouseItem”. Normally there will be a one-to-one relationship here, but exceptionally there will be some bundles where one “saleslistItem” contains several “warehouseItems”. “WarehouseItem” can also be included in several “salesListItems”. At the end of the project, my customer says, testing it, that “saleslistItem” must be able to consist of several “WarehouseItems” of the same kind (like two boxes of smoked ham).
These data is used several places in my code. (ie. doing a sale removes items from the warehouse) If I could just add several the same reference, my code would work without any modifications. But in the implementation of the navigation property the “hashtable”-collection is used, and this collection requires unique entries. Is there a workaround here? Performance is irrelevant as the data amount is small.
If there are no such workaround, is it possible to store values together with the instance of navigation property? Maybe it is implemented as a field in the join-table???
Any other suggestions?
Need a solution so the customer pays the last part of the bill!
So you currently have a 1:1 from SalesListItem toWarehouseItemvia a ForeignKey inSalesListItem`? Sounds like you need:
public class SalesListItem
{
public virutal ICollection<SalesListWarehouseItem> WareHouseItems { get; set; }
}
public class SalesListWarehouseItem
{
public virtual SalesListItem Parent{ get; set; }
public virtual WarehouseItem WarehouseItem { get; set; }
public int Quantity { get; set; } // maybe double?
}
Table already had Delete column for soft delete from web application.
Same table I have pointed to azure mobile services/app.
Also created DeleteMS column for mobile services and used auto mapper in WebApiConfig.cs.
While creating DTO, I rename old Delete column to IsDelete and kept as it is EntityData-Delete property.
Contactdto
public class Contactdto : EntityData
{
public int contact_id { get; set; }
public bool IsDeleted { get; set; }
//public bool DeletedMS { get; set; } //manually added column
}
WebApiConfig.cs
cfg.CreateMap<tblcontact, Contactdto>()
.ForMember(dto => dto.IsDeleted, map => map.MapFrom(tbl => tbl.deleted));
cfg.CreateMap<Contactdto, tblcontact>()
.ForMember(tbl => tbl.DeletedMS, map => map.MapFrom(dto => dto.Deleted));
Is this a right approach? or shall I use same column already we had?
Once record is deleted from mobile app. Will it affect in Web Application after sync service run?
Please help.
If you already implemented soft delete in your web app, it's easiest to just use that exact same column in your Mobile App backend. The only way a record will be marked as deleted is when there is a DELETE call, either through the /tables endpoint or the mobile client.
Also, make sure you are using Mobile Apps, as that is the latest version of the service. See What are Mobile Apps.
Let s say i have two classes
[Table("User")]
public class User
{
public string Name { get; set; }
public string Surname { get; set; }
}
[Table("Manager ")]
public class Manager : User
{
public int Title {get;set;}
}
and i m using entity framework 6.1.2 and table per type approach for saving entity.
Now i want to add a child (i.e. Manager) but there is a parent(i.e. User) for this child.
so what should i do
how do i insert only the child node.
You are mixing some OO principles.
A manager is a user.
This means that if you add a manager to system, you are effectively also adding a user. You can add a user to the system if it is not a manager.
Adding a manager will update both user table and manager table. Adding a user that is not a manager will only add an entry in the user table.
So in summary. All users both normal and managers will appear in the users table. But for the users that are also manager , there will also be a record in the manager table. The information that belongs to a manager is spread over 2 tables in the database. In EF because you have used inheritance you are using only a manager instance, but because it is derived from user, you get access to the user properties as well. Relational concepts and OO concepts are not the same, EF does the mapping between these distinct concepts for you, hence the name Object Relational Mapping.
I'm new to Entity Framework and am trying to learn how to use Code First to load entities from the database.
My model contains a user:
public class User
{
public int UserID { get; set; }
[Required]
public string Name { get; set; }
// Navigation Properties
public virtual ICollection<AuditEntry> AuditEntries { get; set; }
}
Each user can have a set of audit entries each of which contains a simple message:
public class AuditEntry
{
public int AuditEntryID { get; set; }
[Required]
public string Message { get; set; }
// Navigation Properties
public int UserID { get; set; }
public virtual User User { get; set; }
}
I have a DBContext which just exposes the two tables:
public DbSet<User> Users { get; set; }
public DbSet<AuditEntry> AuditEntries { get; set; }
What I want to do is load a list of AuditEntry objects containing the message and the related User object containing the UserID and Name properties.
List<AuditEntry> auditEntries = db.AuditEntries.ToList();
Because I have my navigation properties marked as virtual and I haven't disabled lazy loading, I get an infinitely deep object graph (each AuditEntry has a User object, which contains a list of the AuditEntries, each of which contains a User object, which contains a list of AuditEntries etc)
This is no good if I then want to serialize the object (for example to send as the result in a Web API).
I've tried turning off lazy loading (either by removing the virtual keywords from my navigation properties in the model, or by adding this.Configuration.LazyLoadingEnabled = false; to my DBContext). As expected this results in a flat list of AuditEntry objects with User set to null.
With lazy loading off, I've tried to eager load the User like so:
var auditentries = db.AuditEntries.Include(a => a.User);
but this results in the same deep / cyclic result as before.
How can I load one level deep (e.g. include the user's ID and name) without also loading back-references / following navigation properties back to the original object and creating a cycle?
After much hacking, I've come up with the following potential solution using a dynamic return type and projection in my Linq query:
public dynamic GetAuditEntries()
{
var result = from a in db.AuditEntries
select new
{
a.AuditEntryID,
a.Message,
User = new
{
a.User.UserID,
a.User.Username
}
};
return result;
}
This produces (internally) the following SQL which seems sensible:
SELECT
[Extent1].[AuditEntryID] AS [AuditEntryID],
[Extent1].[Message] AS [Message],
[Extent1].[UserID] AS [UserID],
[Extent2].[Username] AS [Username]
FROM [dbo].[AuditEntries] AS [Extent1]
INNER JOIN [dbo].[Users] AS [Extent2] ON [Extent1].[UserID] = [Extent2].[UserID]
This produces the results that I'm after, but it seems a bit long winded (especially for real life models that would be significantly more complex than my example), and I question the impact this will have on performance.
Advantages
This gives me a lot of flexibility over the exact contents of my returned object. Since I generally do most of my UI interaction / templating on the client side, I frequently find myself having to create multiple versions of my model objects. I generally need a certain granularity over which users can see which properties (e.g. I might not want to send every user's email address to low-privilege user's browser in an AJAX request)
It allows entity framework to intelligently build the query and only select the fields that I have chosen to project. For example, inside each top level AuditEntry object, I want to see User.UserID and User.Username but not User.AuditEntries.
Disadvantages
The returned type from my Web API is no longer strongly typed so I couldn't create a strongly typed MVC view based on this API. As it happens this is not a problem for my particular case.
Projecting manually in this way from a large / complex model could result in a lot of code, seems like a lot of work and has the potential to introduce errors in the API. This would have to be carefully tested.
The API method becomes tightly coupled with the structure of the model and since this is no longer fully automated based on my POCO classes, any changes made to the model would have to be reflected in the code that loads them.
Include method?
I'm still a little confused about the use of the .Include() method. I understand that this method will specify that related entities should be "eager loaded" along with the specified entity. However, since the guidance seems to be that navigation properties should be placed on both sides of a relationship and marked as virtual, the Include method seems to result in a cycle being created which has a significant negative impact on it's usefulness (especially when serializing).
In my case the "tree" would look a little like:
AuditEntry
User
AuditEntries * n
User * n
etc
I'd be very interested to hear any comments about this approach, the impact of using dynamic in this way or any other insights.
I'll try to explain the problem I'm currently facing as simply as possible.
The project I'm currently working on is required to analyze some financial data. For convenience, this data should be stored in a database, so I'm tasked with creating a database model. While the database wasn't required up until now, the application itself has been developed for a number of years and already has all the data types and classes defined, so my task is to match the database model to the classes used by application. Here's a simplified breakdown of a class composition used by application to work with the data.
To start with, there's an abstract Entry class that all other financial data entries are inherited from:
abstract class Entry
{
public Guid ID { get; set; }
public string Name { get; set; }
}
Different financial data comes in different formats an is relevant to different points in time. To reflect this, there's a number of interfaces that are implemented by concrete data types. As an example, lets say that all the data can either be relative to a certain point in time or a period in time. Take currency rate for example. It only changes once a day. GDP, on the other hand, is usually provided for a certain period (either quarterly or yearly). This is reflected by the classes provided below.
class SingleDateEntry : Entry
{
public DateTime Date { get; set; }
}
class PeriodEntry : Entry
{
public DateTime PeriodStart { get; set; }
public DateTime PeriodEnd { get; set; }
}
Furthermore, the data can be represented in different formats. Some data only has a single value, like the currency rate for example, other data can come in data sets, like daily stock prices, which have an opening and closing daily prices, as well as maximum and minimum daily prices.
interface ISingleValueEntry
{
public double Value { get; set; }
}
interface IMinMaxEntry
{
public double MinPrice { get; set; }
public double MaxPrice { get; set; }
}
interface IOpenCloseEntry
{
public double OpenPrice{get;set;}
public double ClosePrice{get;set;}
}
As an example, the daily currency rate, since it is associated with a single day in the past and only has one value, could be represented by a class that looks like this:
class DailyCurrencyRate : SingleDateEntry, ISingleValueEntry
{
}
The stock prices have a number of different values associated with them, so they can be represented like this:
class DailyStockPrice : SingleDateEntry, IOpenCloseEntry, IMinMaxEntry
{
}
And finally, GDP, since it is associated with a period in time and has a single value, would look like this:
class GDP : PeriodEntry, ISingleValueEntry
{
}
Unfortunately, I haven't worked with EF before, and when I tried to implement this simplified scenario of the actual problem I've run into a number of problems, so I would appreciate any suggestions that could help me out resolving them.
To start with, how to deal with multiple interface implementations? As far as I know EF doesn't support multiple inheritance, and by using associations, I don't get classes that implement them, rather it generates classes that contain references to objects that implement these interfaces, which is bad, since it doesn't matches the interface expected by the application. Furthermore, what type of inheritance should be used it this scenario? From what I understood after my research, TPC would be a better strategy, but I might be wrong about that.
Thanks in advance for any pointers, suggestions and "gotchas".
Multiple inheritance is not provided by .NET framework and you don't use multiple inheritance. Each your class inherits only from single parent class. I just tested simple scenario with Code first approach (not part of EF4.0). I modeled three classes in A, B inherited from A and C inherited from B. I stored C as TPH (TPH for code first) without any problems. It will also work with common EF approach.