Is there a way of using EF and/or C# code to migrate data to a new table (and entity), or would I have to use some plain old-fashioned SQL in my EF-Migration?
Here's my situation:
I have an existing OldCarLog class that as used to log user actions on an entity we'll call Car, but now I want to allow logging on other entities and I've created an abstract/generic class BrandSpankingNewActivityLog<TEntity> to make logging of any class easy. So I have Car_Log : BrandSpankingNewActivityLog<Car> along with PartInfo_Log and RepairProcedure_Log.
I want to take all the OldCarLog entities and convert them into their replacement Car_Log
this way I can refactor the OldCarLog into Car_Log and have a standard API for the newly implemented logs without having OldCarLog get confused with any logs derived from BrandSpankingNewActivityLog<TEntity>.
public abstract class BrandSpankingNewActivityLog<TEntity>
{
public long Id { get; set; }
public DateTime ActivityTime { get; set; }
public virtual User User { get; set; }
public virtual TEntity Entity { get; set; }
}
public class Car_Log : BrandSpankingNewActivityLog<Car>
{
//Nothing to see here!
}
public class Car
{
public long Id {get; set;}
//Other car info you don't care about ....
//Yada, Yada, Yada....
public virtual ICollection<Car_Logs> {get;set;}
}
Does that all make sense?
In the DbMigration::Up() make a call using the SQL("TODO: Add SQL"); method.
http://msdn.microsoft.com/en-us/library/system.data.entity.migrations.dbmigration.sql(v=vs.113).aspx
Related
In domain driven design we create bounded contexts. Which means that aggregates don't share a common model.
This image from Microsoft shows how aggregates communicate using commands and events (source).
Assuming those aggregates are at least two different microservices coded in different repositories. How should they share the scheme definition for the commands and events they communicate with? In my case those applications are .net core applications, so serialization and deserialization compatible with .net would be appreciated.
Also, maybe I'm missing some point as I'm new to domain events and communication works different, then I would like to know, what I'm not seeing.
Each service can have an internal model and you can use a Canonical Data Model for the communication between the services.
It's common to have a separate model used for integration that the internal model a service uses.
You can also check all the patterns in enterpriseintegrationpatterns.com and get the book. It's highly recommended.
Edit:
Here's an example with the order system. I'll skip some of the data that the objects will have to simplify the example and try to concentrate on the important parts i.e. the CDM and the internal model.
NOTE For a simple example, it's always difficult to justify some of the decisions as most of the things will be a lot simpler with the additional stuff. The implementation is done this way to help with the example.
Before I continue: Having a CDN will have some overhead in translation from the internal to the external model. If you think you can go without it, do so. Do not make things more complex than they need to be. The problem here is that if you need to change a command or event, this will propagate to all services and will cause a huge ripple effect in your system. The Domain-Driven Design book has a section on the Anti-Corruption Layer. Do check it out.
Why do we use a CDM? For Encapsulation. The same way an object encapsulates its data, the service encapsulates its internals. The CDM is intended to be used only for the communication/integration between the services and is intended to be shared between them.
Sharing the Internal Model of a Service with other Services is a bad thing because it will lock the developers from changing this Internal Model. Also sometimes details from one service can leak to other services and can cause huge problems.
Sharing a Special Data Model designed only for the communication between services is a good thing because it enforces a well-defined model for the communication and your system won't become a mess of events and commands with unknown schemas where every Service posts and consumes whatever it likes. I've seen those kinds of horrors, trust me you don't want that!
This model should be designed at a higher level of abstraction: The system level, having it's processes and flows in mind. It should be void of any details about the internals of the individual services.
What you need is Translation between the internal and external models. Also, you can use ContentFilter and ContentEnricher if you need to filter incoming events or commands and add more data to outgoing events or commands.
// Canonical Data Model
namespace CDM {
public interface ICommand { }
public interface IEvent { }
public class CustomerInfo {
public Guid Id { get; set; }
// notice here the CDM uses the two separate properties for the first and last name
public string FirstName { get; set; }
public string LastName { get; set; }
}
public class LineItemData {
public Guid ProductId { get; set; }
public Quantity Quantity { get; set; }
public Money ListPrice { get; set; }
}
public class PlaceOrderCommand : ICommand {
public CustomerInfo CustomerInfo { get; set; }
public IReadOnlyList<LineItemData> LineItems { get; set; }
}
public class OrderPlacedEvent : IEvent {
public Guid OrderId { get; set; }
public IReadOnlyList<LineItemData> LineItems { get; set; }
}
} // end Canonical Data Model namespace
// Order Service Internals
// the name is done this way to differentiate between the CDM
// and the internal command, do not use it this way into production
public class LineItem {
// the internal one includes the OrderId { get; set; }
public Guid OrderId { get; set; }
public Guid ProductId { get; set; }
public Quantity Quantity { get; set; }
public Money ListPrice { get; set; }
}
public class PlaceOrderInternalCommand {
public Guid CustomerId { get; set; }
public string CustomerFullName { get; set; } // a single full name here
public IReadOnlyList<LineItemData> LineItems { get; set; }
}
public class Event { }
public class OrderPlacedInternalEvent : Event {
public Guid OrderId { get; set; }
public IReadOnlyList<LineItem> { get; set; }
}
// this is part of the infrastructure, received messages and translates/transforms
//them from the external CDM to the internal model.
// This is the input/receiving part of the service
public class CommandDispatcher {
public void Dispatch(ICommand cmd) {
// here we will use a MessageTranslator, check PatternsUsed section
var translator = TranlatorsRegistry.GetFor(cmd);
var internalCommand = translator.Translate(cmd);
Dispatch(internalCommand);
}
}
public class CommandHandler {
public void Handle(PlaceOrderInternlCommand cmd) {
// this will create the OrderCreated event
var order = CreateOrder(cmd);
// this will save the OrderCreated event
OrderRepository.Save(order);
}
}
// Another part of the infrastructure that publishes events.
// This is the output/sending part of the service
public class EventPublisher {
public void Publish(Event event) {
// another usage of the MessageTranslator pattern, this time on events
var translator = EventTranslatorRegisty.GetFor(event);
var cdmEvent = translator.Translate(event);
// publish to kafka or whatever you are using
PubilshToMessageMiddleware(cdmEvent);
}
}
Patterns Used:
Canonical Data Model
MessageTranslator
CommandMessage
EventMessage
I have the following class setup
public abstract class SearchElement
{
public int Id { get; set; }
public SearchElement parent { get; set; }
public int Order { get; set; }
public UserQuery UserQuery { get; set; }
}
public class SearchGroup : SearchElement
{
public virtual ICollection<SearchElement> SearchObjects { get; set; }
public bool IsAndOperator { get; set; }
public SearchGroup()
{
this.SearchObjects = new List<SearchElement>();
}
}
public abstract class SearchCondition<IContext, OutputType> : SearchElement
{
public ComparisonTypes Comparison { get; set; }
public string Value { get; set; }
public abstract Expression<Func<OutputType, bool>> BuildConditionQuery(IContext context);
}
public class SearchPackage : SearchCondition<ISearchContext, ProjectParticipantQuestionnaireResponseGroup>
{
public override System.Linq.Expressions.Expression<Func<ProjectParticipantQuestionnaireResponseGroup, bool>> BuildConditionQuery(ISearchContext context)
{
return this.BuildCondition<ProjectParticipantQuestionnaireResponseGroup, int>(r => r.Package.Id, int.Parse(this.Value), this.Comparison);
}
}
Now for some reason, when in the EntityFramework context I specify:
public DbSet<SearchElement> SearchElements { get; set; }
The SearchGroup class gets detected and the appropriate fields get created in the SearchElement table. However, the SearchPackage class does not get detected and it's fields are not created in the SearchElement table.
I can of course create a DbSet for the SearchPackage, but there are multiple similar classes (same inheritance, although some with difference values) and I don't want to create a DbSet for each of them. Does anyone has suggestions about what I can do?
For clarity: I am using Entity Framework 6.1.3 and C# 4.5.1
EF 6 cannot map a CLR generic type. (Sorry, I can't find an authoritative reference on this right now.) This is the problem, not one of inheritance generally. When EF traverses your inheritance "tree," it gets to SearchCondition<,> and gives up.
Finding a way around this will probably require a rethinking of your object model to something more serialization-friendly. Is there a way that you can split your object-model into a set of services (that might contain generics) that interacts with a set of more easily mapped DTOs?
Another (possible, untested) option: Make an ISearchElement mapped interface. SearchPackage should implement it directly. This way, SearchPackage--and other SearchCondition<,> implementors should get "picked up" by EF inheritance traversal.
My application has a business logic layer, and a data access layer. I want to give only the data access layer access to the database model. Now, I can easily do this, but then my UI classes cannot access the database classes like Reminder:
namespace Database
{
using System;
using System.Collections.Generic;
public partial class Reminder
{
public long Id { get; set; }
public string Name { get; set; }
public string Date { get; set; }
public string RepeatType { get; set; }
public string Note { get; set; }
public long Enabled { get; set; }
public string SoundFilePath { get; set; }
public string PostponeDate { get; set; }
public Nullable<long> EveryXCustom { get; set; }
public string RepeatDays { get; set; }
public Nullable<long> DayOfMonth { get; set; }
}
}
which is inside the database class library
I use this reminder class to store reminders. In my UI classes I use this class for various reasons.
To make use of this Reminder class, I simply add a reference to the class library that needs to use it. This works fine, but the problem is that every class library that references this, can alter the database like this.
If I'm not using Entity Framework, I could simply have a Reminder class outside the model (because there is no model) and load reminders from the database into that and extract them without using Entity Framework.
Here's an example of why I need to use the Reminder class in my UI classes (this is just a small code sample of one UI class)
This code is inside a timer that ticks every 30 seconds
// We will check for reminders here every 30 seconds.
foreach (Reminder rem in BLReminder.GetReminders())
{
// Create the popup. Do the other stuff afterwards.
if(rem.PostponeDate != null && Convert.ToDateTime(rem.PostponeDate) <= DateTime.Now && rem.Enabled == 1)
{
allowRefreshListview = true;
// temporarily disable it. When the user postpones the reminder, it will be re-enabled.
rem.Enabled = 0;
BLReminder.EditReminder(rem);
MakePopup(rem);
}
else if(Convert.ToDateTime(rem.Date.Split(',')[0]) <= DateTime.Now && rem.PostponeDate == null && rem.Enabled == 1)
{
allowRefreshListview = true;
// temporarily disable it. When the user postpones the reminder, it will be re-enabled.
rem.Enabled = 0;
BLReminder.EditReminder(rem);
MakePopup(rem);
}
}
GetReminders will do get the reminders from the database and put them in reminder objects
using (RemindMeDbEntities db = new RemindMeDbEntities())
{
localReminders = (from g in db.Reminder select g).ToList();
db.Dispose();
}
You can create separate project called i.e. Shared and put there all classes which are used in many projects. Then you need to reference this project by UI project and data access project (and by others which use these classes).
Both will have access to shared classes and UI won't be able to call data access layer directly.
You can also create interface outside of data access layer but if your classes are DTOs (Data Transfer Object) first option will be better.
If im not using the entity framework, i could simply have a reminder
class outside the model
You could create an interface instead of a class outside of the model in a shared assembly:
public interface IReminder
{
public long Id { get; }
public string Name { get; }
public string Date { get; }
public string RepeatType { get; }
public string Note { get; }
public long Enabled { get; }
public string SoundFilePath { get; }
public string PostponeDate { get; }
public Nullable<long> EveryXCustom { get; }
public string RepeatDays { get; }
public Nullable<long> DayOfMonth { get; }
}
Your Entity can than implement the interface:
public partial class Reminder : IReminder
{
//...
}
Maybe you want to make your Entities only internal visible and expose public service methods like IEnumerable<IReminder> GetReminders()
I am building an ASP Web API application and this time I thought I will go with the MVC pattern. I got along with most of the stuff, but there is one thing of which I am unsure. First of all my project consists of the following:
Data Layer
Business Layer
Model Layer (just the model with the properties)
Service Application (here are my controllers)
every one of them in a separate project
Lets say I have the following controller
public class TestController : ApiController
{
ISomeService _someBusiness;
public TestController(ISomeService someBusiness)
{
_someBusiness = someBusiness;
}
public **SomeModelObject** GetModelObject(ind id)
{
return _someBusiness .GetSomeModelObject(id);
}
}
Now my problem is the return value of GetModelObject(int id). Here it says SomeModelObject. That implies that my Service application (or my controller) has to know everything about the model which is being used (so I dont see the point in defining it in a separate .dll). One way would be to define the model (precisely the get/set mothods) as an interface, but I think that it would be too much that every model class has an interface (mostly because, as I said, just the properties are being stored inside the model), and despite that I just does not feel right to build an interface for a class which only stores data. So, is there any generic response type which is being used in this case (even some completely different approach), or do I have to use my model classes (or may i just always use string and it is being converted to the appropriate format by the client) ?
There's a good reason to use an interface to hide the complexity of the model object. It holds data, sure. But it holds unnecessary data that is only meaningful to the data layer. Take this EF model:
public class Employee
{
public int Id { get; set; }
public string EmployeeNumber { get; set; }
public string Name { get; set; }
public virtual Collection<TimeCard> TimeCards { get; set; }
public int DepartmentId { get; set; }
public virtual Department Department { get; set; }
}
This is a fairy common EF model. It contains a surrogate key Id, and a foreign key DepartmentId. Those values are meaningless except for the database and, by extension, for entity framework. EmployeeNumber is the natural key which uniquely identifies the entity in the user's domain.
Outside of database access, you should really only deal with natural data values. You could do this by declaring yet another data-carrying class in the Business layer and perform mapping, or a better idea is to use an interface to hide all of the members that are not useful.
public interface IEmployee
{
string EmployeeNumber { get; }
string Name { get; set; }
ICollection<ITimeCard> TimeCards { get; }
IDepartment Department { get; set; }
}
Notice the lack of some setters in the interface. You'll never want to change the EmployeeNumber because that is the natural key for the entity. Likewise, you'll never assign a collection object to the TimeCards property. You'll only ever iterate over, add, or remove them.
Now your Employee class becomes
public class Employee : IEmployee
{
public int Id { get; set; }
public string EmployeeNumber { get; set; }
public string Name { get; set; }
public virtual Collection<TimeCard> TimeCards { get; set; }
ICollection<ITimeCard> IEmployee.TimeCards { get { return TimeCards; } }
public int DepartmentId { get; set; }
public virtual Department Department { get; set; }
IDepartment IEmployee.Department { get { return Department; } set { Department = value; } }
}
In your business layer and above, you'll only use variable of IEmployee, IDepartment, and ITimeCard. So you are exposing a tighter API to the higher layers, which is a good thing.
You could try to use a generic approach at controller level:
public class BusinessController<T> : ApiController
{
ISomeService _someBusiness;
public TestController(ISomeService someBusiness)
{
_someBusiness = someBusiness;
}
public T GetModelObject(ind id)
{
return _someBusiness.GetSomeModelObject(id);
}
}
Finally your controlers inherit from BusinessController instead of ApiController:
public class TestController : BusinessController<SomeModelObject>
{
}
You could also take advance of the templating to inject the right "ISomeService" by using an IoC container and a bootstrapper.
I'm creating a web api program using entity framework. So as the basis, I have an sql server database which I'm connected to with entity framework trought my web api program. Using an add-on for entity framework, I'v generated classes according to my database tables. However i don't want to use these classes for my webservices because I don't need to display some of the attributes generated by the entity framework and little bit tricky with all the proxies problems. These attributes are especially generated because of the foreign keys. As below, for this generated class, I don't need to display "Societe" object and "Utilisateur" object:
public partial class FonctionnalitePerUser
{
public int FonctionUserLngId { get; set; }
public int FonctionUserLngUserId { get; set; }
public int FonctionUserLngSocieteId { get; set; }
public virtual Societe Societe { get; set; }
public virtual Utilisateur Utilisateur { get; set; }
}
I would need some advice to avoid displaying that entities in my webservices.
I was thinking about 3 possibilities:
As it's a partial class, I might create an other partial class with the same name where I put the attributes that I need and override the constructor.
I might inherit a custom class from that one to override the constructor in order to get one structured as I need.
I might create Management classes with functions that create the perfect objects that I need for my webservices. I mean functions that convert "FonctionnalitePerUser" object to "FonctionnalitePerUserCustom" objects.
These are the 3 solutions that I've found. In order to get the best performance, I was wondering if anyone can give me some advise about that or either propose some other solutions.
Thanks in advance
If your using Newtonsoft Json.NET which I think is the default in MVC5 then you can attribute your properties to tell newtonsoft what to serialize and what to ignore.
public class Car
{
// included in JSON
public string Model { get; set; }
public DateTime Year { get; set; }
public List<string> Features { get; set; }
// ignored
[JsonIgnore]
public DateTime LastModified { get; set; }
}
or if you have more properties you want to ignore than you want to serialize you can do this:
[DataContract]
public class Computer
{
// included in JSON
[DataMember]
public string Name { get; set; }
[DataMember]
public decimal SalePrice { get; set; }
// ignored
public string Manufacture { get; set; }
public int StockCount { get; set; }
public decimal WholeSalePrice { get; set; }
public DateTime NextShipmentDate { get; set; }
}
this information was taken from here.
In general, it is often useful to expose a different type of object for a web service API than for persistence. This is for exactly the reason you state: because you don't need to expose all of that persistence stuff to the rest of the world (clients).
Usually, you would map the information that you want to expose from your persistence model (EF entities etc) to a view model object (or DTO).
So, I would say your option 3 is on the right track.
I might create Management classes with functions that create the
perfect objects that I need for my webservices. I mean functions that
convert "FonctionnalitePerUser" object to
"FonctionnalitePerUserCustom" objects
There are several tools out there that help with the converting or mapping of the objects. One is AutoMapper which will map by convention. This can save a lot of mapping code.