Effort Entity Framework Sequence contains not matching elements - c#

So I've been trying to setup Effort and am not having much success. Looking on their site and people's comments it looks pretty straightforward.
I started small because I just wanted to test if it works. The error I get is
"Sequence contains no matching element"
I've added a constructor like so to the dbcontext.
public ApplicationDbContext(DbConnection connection)
: base(connection, true)
{
}
My setup like so for my test
var connection = Effort.DbConnectionFactory.CreateTransient();
var context = new ApplicationDbContext(connection );
Just a test to see if it works
context.Set<MyType>().Add(new MyType() {Description = "test"});
Class for MyType
public class MyType
{
[Key]
public byte Id { get; set; }
[Required, MaxLength(50)]
public string Description { get; set; }
}
I have also tried this with the createpersistent. Same result.
I am using ef6 code first, mvc 5, .net 462.

Found the problem I had another data model with a property containing the following annotation. It didn't like it. Commented it out and it worked.
[Column(TypeName = "XML")]

Related

Mapping a User entity into a User DTO in .NET Core

I'm developing a web app that contains a User entity that is derived from .NET Core's IdentityUser. Lets suppose there is another entity called Comment which has a relation to a user (the user who posted the comment):
public class User : IdentityUser
{
public string SomeExtraField { get; set; }
}
public class Comment
{
//Owner (Creator) of the feedback
public User User { get; set; }
//body of the comment
public string Body { get; set; }
}
Now suppose I have an API endpoint that returns all of the comments in the system. If I query for all comments and include the User relation, when the object gets serialized, everything in the User class is serialized and sent to the client (including the users hashed password, etc). Obviously I don't want this. So I've created a CommentService layer that grabs the Comments from a CommentRepository. From my understanding, the service layer should do the job of mapping the raw Comment object into a Comment DTO, which only contains data that should be sent to the client. I've defined a comment and user DTO like this:
public class UserOutput
{
public string Id { get; set; }
public string SomeExtraField { get; set; }
}
public class CommentOutput
{
public UserOutput User { get; set; }
public string Body { get; set; }
}
Then in my service layer I have something like the following:
//Fetch all comments
var list = await _repository.ListAsync();
//Map comments to DTO
var result = list.Select(x => new CommentOutput
{
Body = x.Body,
User = new UserOutput
{
Id = x.User.Id,
SomeExtraField = x.User.SomeExtraField,
}
});
This all seems to work great. However I can foresee one problem. Lets say I have a large system with Comments, Posts, Likes, Private Messages, etc. I can map them all in a similar fashion above. Then one day I decide to add another field to the UserOutput DTO. Now I have to go through potentially hundreds of mapping code like the sample above to map the new field properly, and whats worse is the compiler wont tell me if I've missed anything. I would like to have a function somewhere that maps a User to a UserOutput but I don't know where it should go.
I've seen some suggestions to put a constructor to the DTO that does the mapping:
public class UserOutput
{
public UserOutput(User user)
{
Id = user.Id;
SomeExtraField = user.SomeExtraField
}
public string Id { get; set; }
public string SomeExtraField { get; set; }
}
but I've seen people against this because it tightly couples the DTO with the Entity. I've also seen suggestions of using Auto Mapper but is also seems an equal amount of people are against it.
Where should I place code that can perform these DTO->entity and entity->DTO mappings so I don't repeat myself all over the place?
Try to check out AutoMapper.
This library will help you to map the Entity Class into the ViewModel.
The way to use it is pretty straightforward.

Effort (C#) - 'Sequence contains no matching element' when seeding data to any of my entities

I am trying to build some unit tests for a few web service calls in my project. I am using Entity Framework 6.1.3 in my project to retrieve the data at the service layer (with a code-first approach). I did some research on how to Mock a DatabaseContext object and I found out that Effort can do this.
I followed the documentation when implementing Effort in my unit tests but when I try to seed data to my entities I get a "System.InvalidOperationException: 'Sequence contains no matching element'" exception. I am not entirely sure why this is happening. Any help will be much appreciated. Thanks!
Here is how the code looks like....
//THE CALLER -- Doing what Effort suggests to do.
var dbConnection = DbConnectionFactory.CreateTransient();
FakeDbContext = new FakeDbContext(dbConnection);
DatabaseSeed.AddTestData(FakeDbContext);
Here is where I seed data to the entities...
public static void AddTestData(IFakeDbContext context)
{
//**************** IT CRASHES HERE *********************
context.FakeEntity1.AddOrUpdate(new FakeEntity1
{
Name1 = "TestingName1",
LastName1 = "TestingLastName1"
});
context.SaveChanges();
}
Here is my Entity Model...
[Table("rpt.FakeEntity1")]
public partial class FakeEntity1 : IFakeEntity1
{
[Key]
[Column(Order = 0)]
[StringLength(20)]
public string Name1 { get; set; }
[Key]
[Column(Order = 1)]
[StringLength(20)]
public string LastName1 { get; set; }
}
Here is my DatabaseContext...
public partial class FakeDbContext: IFakeDbContext
{
public FakeDbContext(DbConnection dbConnection)
: base(dbConnection, true)
{
//Effort requires this.
}
}
public interface IFakeDbContext :IDisposable
{
DbSet<FakeEntity1> FakeEntity1 {get; set;}
}
I also have another class FakeDbContext.Base that overrides OnModelCreating.
Here is the Stack Trace:
StackTrace
The stack trace shows that the exception is thrown when the data provider is looking for a "store type from name". This indicates that you're using a data type that Effort doesn't support. This is confirmed by an issue in the Effort project.
hope this helps.
Many answers says you have to add FirstorDefault() in your EF statements but this error also occurs in the incorrect properties using data annotations.
When using Data Annotations, be careful with the properties that you add.
Example below, I missed the TypeName = "string", which should have been nvarchar as it is the data type in the database.
Also, take note of the Order = n,(starts with 0)
Encountered this while updating a past colleagues source code.
[Display(Name = "Name")]
[MaxLength(4000)]
[Column("Name", Order = 14, TypeName = "string")]
public string Name { get; set; }
then I corrected my code with
[Display(Name = "Name")]
[MaxLength(4000)]
[Column("Name", Order = 15, TypeName = "nvarchar")]
public string Name { get; set; }
:)

serialized property to complex type in dto with linq and automapper

I'm having a hard time figuring something out that seems as a "easy" problem.
I'm working with Microsoft Azure mobile apps .Net backend, a MSSQL database, Entity Framework code-first and AutoMapper.
So i have the following objects:
public class Route
{
public string Id { get; set; }
[...] //some other properties
public string SerializedGoogleRoute { get; set; }
}
public class DtoRoute
{
public string Id { get; set; }
[...]
public DtoGoogleRoute GoogleRoute { get; set; }
}
public class DtoGoogleRoute
{
[...] //only strings, ints,...
}
So what I want to do is: In the database save the GoogleRoute as a serialized string because it consists of many properties and I don't need them in different columns - I just want it as a serialized string in one column on the route entity.
When the Route object is projected to the DtoRoute object I want the GoogleRoute to be serialized and vice versa.
Because I'm working with LINQ / queryables I am limited to a few AutoMapper mapping options (see AutoMapper wiki). And with none of these I can't get it to work.
The problems I'm facing/what I tried:
I can't serialize/deserialize the string to the DtoGoogleRoute on mapping (with MapFrom or ConstructProjectionUsing) because LINQ obviously cannot transform the JsonConvert.Serialize/Deserialize methods to SQL statements.
I tried having a DtoGoogleRoute property in the Route object and a string property in the DtoRoute object with getters/setters doing the (de)serialization. This works almost perfectly in a custom API controller but because of the OData query filter the azure mobile app .Net backend uses in the tablecontrollers again only the serialized string property gets returned to the client (because OData/LINQ does not know of the other property).
Another option was making a complex type out of DtoGoogleRoute with Entity Framework - this works fine but not with AutoMapper because AutoMapper can't handle complex types.
For now I'm working with a custom API controller and this works. But it would be better to use the tablecontrollers because they support offline sync.
I can't imagine such a simple thing (at least I thought it was a simple thing) can't be done or is so hard to do. But maybe the problem is all the components (tablecontroller, OData, LINQ, EF, AutoMapper) involved.
I would really be thankful if someone could help.
[EDIT]: I think the fact that it works with a normal api controller and not with a tablecontroller has something to do with OData. I tried putting the same code in a tablecontroller method and in an API controller method. when calling the API controller method I can see on the server that it just calls this function and returns all the right properties to the client (checked with fiddler). But when calling the tablecontroller method the tablecontroller method "rewrites" the URL to a OData URL --> I think this is because of some of the EnableQuery or other OData attributes. Because here (although not AutoMapper but it seems like a similar project from Microsoft) it says that the EnableQuery attribute is called twice - also when the request leaves the server. And I think it cuts of the GoogleRoute property because it does not know about this property in the OData metadata or something like that.
You can achieve it like this -
internal class RouteToDtoConverter : TypeConverter<Route, DtoRoute>
{
protected override DtoRoute ConvertCore(Route source)
{
return new DtoRoute
{
Id = source.Id,
GoogleRoute = JsonConvert.DeserializeObject<DtoGoogleRoute>(source.SerializedGoogleRoute)
};
}
}
internal class DtoToRouteConverter : TypeConverter<DtoRoute, Route>
{
protected override Route ConvertCore(DtoRoute source)
{
return new Route
{
Id = source.Id,
SerializedGoogleRoute = JsonConvert.SerializeObject(source.GoogleRoute)
};
}
}
public class Route
{
public string Id { get; set; }
public string SerializedGoogleRoute { get; set; }
}
public class DtoRoute
{
public string Id { get; set; }
public DtoGoogleRoute GoogleRoute { get; set; }
}
public class DtoGoogleRoute
{
public int MyProperty { get; set; }
public int MyProperty2 { get; set; }
}
AutoMapper.Mapper.CreateMap<Route, DtoRoute>()
.ConvertUsing(new RouteToDtoConverter());
AutoMapper.Mapper.CreateMap<DtoRoute, Route>()
.ConvertUsing(new DtoToRouteConverter());
var res = Mapper.Map<DtoRoute>(new Route
{
Id = "101",
SerializedGoogleRoute = "{'MyProperty':'90','MyProperty2':'09'}"
});
var org = Mapper.Map<Route>(res); //pass

Entity Framework Code First, nonempty setter or getter?

I am working with an EF Code First project, and all is well. I have a simple Class, Customer. In my Customer Class I have a field I want to encrypt (Yes, I know I can encrypt at the DB level but requirements dictate I encrypt at the Domain/Code level), so I am hoping that I can do something like the following:
public class Customer
{
public int CustomerID { get; set; }
public string FieldToEncrypt { get; set { _FieldToEncrypt = MyEncryptionFunction.Encrypt(); } }
}
However, I assume that if the setter has a definition, entity framework code first may ignore that property when generating the schema. So my question is, is there a way to do EF Code First with provided getters/setters, or should I move this functionality into a constructor? Should I override one of the methods/events that happens when the Context is saving, instead?
EDIT ********************
As a note, I am using DataService to transmit the data over an OData protocol service. This automatically generates insert/update/select methods. Some of the suggestions require creating a second property, but the DataService class does not seem to pass through NotMapped properties. This throws a bit of a kink into my earlier question.
public class Customer
{
public int CustomerID { get; set; }
public string EncryptedField { get; private set; }
[NotMapped]
public string Field
{
get { return MyEncryptionFunction.Decrypt(EncryptedField); }
set { EncryptedField = MyEncryptionFunction.Encrypt(value); }
}
}

Passing DTO to my ViewModels constructor to map properties

In my solution I have two projects.
Project 1 (Core)
Mapping SQL to DTO using Dapper
Project 2 (WebUI - ASP.NET MVC 4)
Here I use a ViewModel per View.
Examples of a Controller
[HttpGet]
public ActionResult Edit(int id)
{
// Get my ProductDto in Core
var product = Using<ProductService>().Single(id);
var vm = new ProductFormModel(product);
return View(vm);
}
Examples of a ViewModel
public class ProductFormModel : BaseViewModel, ICreateProductCommand
{
public int ProductId { get; set; }
public int ProductGroupId { get; set; }
public string ArtNo { get; set; }
public bool IsDefault { get; set; }
public string Description { get; set; }
public string Specification { get; set; }
public string Unit { get; set; }
public string Account { get; set; }
public decimal NetPrice { get; set; }
public ProductFormModel(int productGroupId)
{
this.ProductGroupId = productGroupId;
}
public ProductFormModel(ProductDto dto)
{
this.ProductId = dto.ProductId;
this.ProductGroupId = dto.ProductGroupId;
this.ArtNo = dto.ArtNo;
this.IsDefault = dto.IsDefault;
this.Description = dto.Description;
this.Specification = dto.Specification;
this.Unit = dto.Unit;
this.Account = dto.Account;
this.NetPrice = dto.NetPrice;
}
public ProductFormModel()
{
}
}
Explanation:
I'll get my DTOs in my controller using a service class in the project (Core).
Then i create my ViewModel and pass the DTO to the constructor in ViewModel.
I can also use this view to add a new Product because my ViewModel can take a empty constructor.
Does anyone have experience of this. I wonder if I am in this way will have problems in the future as the project gets bigger?
I know this has nothing to do with Dapper. But I would still like a good way to explain my solution.
I think you will be fine using your current approach. More importantly, start out like this and refactor if you start to encounter problems related to your object mapping code (instead of thinking too much about it beforehand).
Another way to organize mapping logic that I use sometimes is to employ extension methods. That way, the mapping code is kept separate from the view model itself. Something like:
public static class ProductMappingExtensions
{
public static ProductFormModel ToViewModel(this ProductDto dto)
{
// Mapping code goes here
}
}
// Usage:
var viewModel = dto.ToViewModel();
Yet another approach would be to use a mapping framework like AutoMapper - this is a good fit in particular if your mapping logic is simple (lots of 1:1 mappings between properties).
But again, start simple and refactor when you need to.
I realize that this is a little bit late answer, but maybe it will help someone in the future.
This way of doing mapping between objects breaks the 'S' of the SOLID principles, because the responsibility of the ViewModel is to prepare data in its properties to be ready to use by the view and nothing else, therefore, mapping objects should not be on it's responsibilities.
Another drawback of this way is that it also breaks the 'Loose Coupling' OO principle as you ViewModel is strongly coupled with your DTO.
I think, even when we are in the very first step of the project, there are some importants OO principles that we should never break, so using mapper classes, either auto (AutoMapper, ValueInjecter ...) or manual, is definitely better.

Categories