How do I update a model in a ReliableDictionary? - azure-service-fabric

Consider this mock scenario where I have the following class:
public class Person {
public Guid Id {get;set;}
public string Name {get;set;}
public Address Address {get;set;}
}
I currently have a ReliableDictionary(Guid,Person). I'd like to change my Person model by splitting out the Address, to the following:
public class Person {
public Guid Id {get;set;}
public string Name {get;set;}
}
public class Address {
public Guid Id {get;set;}
public string Street {get;set;}
...
}
I would then have two ReliableDictionaries, one for persons and one for addresses.
What is the proper way to split these entities and migrate the data during an upgrade? I feel like there used to be documentation on this, but I can no longer find it.
Thanks!

An important requirement is that your model needs to be backward compatible. A stored model should be able to load, no matter the changes to your model.
Converting all stored models requires you to loop through the stored models, make changes and store them again. You need to write specific code for this. This could be included in the microservice, or you could create a temporary microservice which calls the microservice which holds the data. After the conversion is done you can remove the code or the microservice.
You could also do this 'on the fly'. Whenever a model is loaded during production you check the version number (you need to specify a version field on your model). If the version is below a certain value, convert it.

Related

Need for using different DTOs on web api resource

I have couple of DTOs that I am using in WEB API and I have noticed that I am reusing same properties over and over again.
For example
public class Response
{
public int Id {get;set;}
public DateTime CreatedOn {get;set;}
public string Name {get;set;}
public string Code {get;set;}
}
public class InsertRequest
{
public string Name {get;set;}
public string Code {get;set;}
}
Is there really a need to specify InsertRequest for a resource, since DTOs are processed later in the code? It could be misleading to have property Id available in code even if Id would not be inserted.
On the other hand if Id is declared as nullable, it can be misleading since Id in Response should not be nullable, so I am in doubt should these two request be split or should they all be in one representing a resource?
The situation you describe is pretty common for situations where you have to create / update entities.
I would recommend you keep yours as they are. CreatedOn makes no sense when you want to update and Id, well, it'll never change once created, so again, it makes no sense to have it in a change entity. Plus, chances are that you will provide your Id in the route so the actual entity doesn't need it anyway:
PUT against:
www.somedomain.com/entity/id
entity doesn't need id field as its coming from the URI.
Yes, you can argue that you will end up with entities with duplicate fields, but at the same time you'll have a clean API which makes sense and that's more important as this is what the clients will be seeing and using.
One more thing, I am in favor of keeping a clear naming convention so if one entity is InsertRequest then the other will be UpdateRequest.

Creating custom id with mongo C# driver

I'm trying to set the Id property of my class as combination of another 2 properties:
public class Student
{
public string Id {get;set;}
public Guid StudentNumber {get;set;]
public string SchoolId {get;set;}
}
I want that StudentNumber and SchoolId to be the Id of the object when I save it.
How can it be done?
Have a look at the IdGenerator classes to custom create an id from the two properties.
http://docs.mongodb.org/ecosystem/tutorial/serialize-documents-with-the-csharp-driver/
You'll need to create a new IdGenerator class which implements the IIdGenerator interface (docs). There are two simple methods to implement.
Do note that a document's _id cannot be changed once saved. You'd need to resave it as a new document. So, if the SchoolId property changes, you may need to recreate the document.
Also, you might just consider creating a composite index for the two fields and leave the _id as an ObjectId.

Reference data look-up in Entity Framework 4.2 code first

I’m putting together a code first model that has a lot of reference data. This model is based around applications, servers, and build deployments. Thus, there are a lot of many to many relationships. The pain that I’m feeling is that new records are being placed in the entity tables which I’m attempting to use as reference data. For example, we have a list of servers. I only want to see a server ONCE in the table. For all the entities referring to that server, I want them to use that row. The same can be said of my ServerRoles and Applications tables. These tables contain static data that I’m seeding and should rarely change.
I know I could solve this with look-ups and hand wiring, but I would think EF would comprehend this scenario.
Using Entity Framework code-first you can create an immutable object with protected parameter less constructor and private set properties.
It works for sure with EF 5 Beta.
[Update]
Tested also with EF 4.3.1, it works.
public class Nation
{
protected Nation() {}
public Nation(Guid id, string name)
{
Id = id;
Name = name;
}
public Guid Id { get; private set; }
public string Name { get; private set; }
}

Auditing many-to-many relationships in Entity Framework?

I have been reading some artices about using the RelationshipManager to gain access to the entries that have related data. It is still unclear to me what the best way to audit when an entity whose related data is added or updated.
Sample Classes:
public class Rfi
{
public Guid Id {get;set;}
public string Number {get;set;}
public virtual ICollection<Attachment> Attachments {get;set;}
}
public Class Attachment
{
public Guid Id {get;set;}
public string Name {get;set;}
public string Description {get;set;}
public string FileName {get;set;}
public string Path {get;set;}
}
Sample Mappings:
public class RfiMapping: EntityTypeConfiguration<Rfi>
{
public Rfimapping()
{
HasMany(r => r.Attachments).WithMany().Map(m =>
{
m.MapLeftKey("RfiId");
m.MapRightKey("AttachmentId");
m.ToTable("Rfi_Attachments");
});
}
}
I am using the Repository and Unit Of Work patterns. My UoW inherits from DbContext. A repository call may look like this:
public void AddAttachmentToRfi(Attachment attachment, Guid rfiId)
{
var rfi = _rfiRepository.FindById(rfiId);
rfi.Attachments.Add(attachment);
_rfiRepository.UnitOfWork.Commit();
}
Is it possible , in an overridden SaveChanges method, to figure out that an Attachment entity was added to an Rfi entity? When I traverse the, say ChangeTracker.Entries, I am not seeing its state being set to modified. Which makes sense, because I am only adding to the relationships and not the entity directly.
I know to cast my DbContext to an IObjectContextAdapter, but I am not sure what I need to do with the RelationshipManager to get the changes made to any of the relationships. I am also curious to know if I were to update an Attachment's Description property later on, if I can still see what changes were made to any related data.
My goal with this is, the user interface for the Rfi allows users to attach files (Rfi is obviously not the only entity that can have attachments). I need to show a history of everything that happens to an Rfi. This means if an attachment is added I need to audit it. If the attachment's data is updated, I need to audit those changes and show that they were updated via the Rfi interface. This may get complicated if that attachment is shared with another entity, but I will cross that road later.
As you say you are not changing any of the entities only the relationship between them.
EF will then convert this to an insert into or delete from the Rfi_Attachments table.
One way to audit this is to add a database trigger that writes an entry to a log table, each time an entry is added or deleted.

How to deal with "computed" property in Entity Framework 4.1?

I have a model as below:
public class Post
{
public int Id {get;set;}
public virtual ICollection<Comment> Comments {get;set;}
public virtual ICollection<Reader> Readers {get;set;}
public int Value {get;set;}
}
The rule is Value = Comments.Count * 2 + Readers.Count.
What is the right and convenient way to deal with the "computed" property of "Value"?
I think it is the best that the "Value" can be calculated and saved automatically when Comments or Readers add/remove element.
but the "DatabaseGeneratedAttribute" seems no use here.
Thank you!
This is not supported. There is no way to make Value available for linq-to-entities queries if it is not mapped to database column. In case of EF using EDMX for mapping this can be sometimes solved by using custom mapped SQL function or model defined function but code first mapping doesn't support anything of that. Other way is to create database view and map your entity to view but in such case entity will be read only.
Once you use .NET code for defining value it is always only client side property computed from data loaded from database. If you don't want to recompute property every time you need observable collections with event handler changing precomputed value each time the collection changes.
DatabaseGenerated attribute just marks your property as generated by database - in such case you cannot change its value and database must ensure that correct value will be stored in your table.
I think your column value is based on two mapped properties. Use NotMappedAttribute to Exclude a Property from the Database Schema and Load values in runtime.
public class Post
{
public int Id {get;set;}
public virtual ICollection<Comment> Comments {get;set;}
public virtual ICollection<Reader> Readers {get;set;}
[NotMapped]
public int Value
{
get return Comments.Count * 2 + Readers.Count;
}
}
You may use the DatabaseGenerated attribute and then create triggers in the db for calculating the Value. You can create the triggers in the migrations, or db seed method.