Breeze and the Entity Data Model with Navigation Property throws error - entity-framework

Using Breeze and a simple one to many relationship created using the Entity Data Model designer gives me the following error:
TypeError {stack: "TypeError: Cannot read property '$type' of null↵
…//localhost:55494/Scripts/jquery-1.9.1.js:1083:7)", query: null}
I figured out that Breeze throws that error when using a Navigational Property and that property is Null. What am I missing here?
I got the following relationship:
Controller code:
private readonly EFContextProvider<ModelContainer> _contextProvider = new EFContextProvider<ModelContainer>();
[HttpGet]
public string Metadata()
{
return _contextProvider.Metadata();
}
[HttpGet]
public IQueryable<Appointment> Appointments()
{
return _contextProvider.Context.Appointments;
}
Using the following query:
var query = breeze.EntityQuery.from('Appointments');
This is the raw JSON output:
[{"Id":1,"Date":"2013-01-01T00:00:00","Comments":"Testing","Car":null}]

Do you have a [BreezeController] attribute on your ApiController?

Related

How to get a DbFunction to accept a DateOnly parameter in EF Core?

Yesterday I managed to call the SQL EOMONTH function from EF Core thanks to this answer, but now I need to call it using the new DateOnly type:
class MyContext : DbContext
{
[DbFunction(IsBuiltIn = true)]
public static DateTime EOMONTH(DateOnly startDate)
=> throw new InvalidOperationException(
"Don't call EOMONTH directly. It must to be translated to SQL " +
"inside of a LINQ query.");
}
I've already implemented the support for using as a column in the entities:
protected override void ConfigureConventions(ModelConfigurationBuilder builder)
{
builder.Properties<DateOnly>()
.HaveConversion<DateOnlyConverter, DateOnlyComparer>()
.HaveColumnType("date");
}
but the above definition of EOMONTH throws the following exception when starting to run the API:
How can I get it to accept this custom type as a parameter for a DbFunction?

Why does EntityFramework populate my NotMapped field with a trash value

Hello i am retrieving a IEnumerable<Something> using Entity Framework and this Something has an IEnumerable<SomethingElse> property that has the attribute [NotMapped] over it.
Why does entity framework populate this IEnumerable<SomethingElse> field with some unknown object that is neither null but can't be interogated with Linq throwing the following exception:
System.ArgumentNullException: 'Value cannot be null. (Parameter 'source')'
public class Something
{
[NotMapped]
public IEnumerable<SomethingElse> Items{get;set;}
}
public struct SomethingElse
{
//some fields
}
Insertion:
When i insert the list some elements have the NotMapped field null, while others not:
List<Something> toBeInserted=new List<Something>{ new Something{Items=null},new Something{Items=new[]{ new SomethingElse{}}};
//dbcontext insert the list....
Retrieval
List<Something>somethings=(await this.[SomeDBContext].Somethings).ToList();
Now at retrieval some elements have the NotMapped property null as it should be,while someothers have this weird non-null IEnumerable<SomethingElse>d_6that throws exception on any Linq interogation:
var weirdElement=somethings.First();
weirdElement.Items.Count(); //throws
weirdElement.Items.Any();throws
P.S I have checked this post regarding computed properties and it says: Materialize the list when you fetch it from the database to resolve the computed properties.That is what i have done.
I issue (await this.DBContext.Somethings).ToList() to no avail.
Some Something's still have their IEnumerable<SomethingElse> property not null.
Later Edit
This is a picture with what the
not mapped property of the element looks like:
I am computing the IEnumerable<SomethingElse> using an extension method:
public class Extension
{
public static IEnumerable<SomethingElse> Compute(this IEnumerable<SomethingSomethingElse> someOthers){}
}
The name of the type of the field IEnumerable<SomethingElse> is <Compute>d_6

Entity Framework execute stored procedure with params

Ok, hope to not get too many flags, but it's to annoying.
I have a method in my controller which calls a method from another class:
offerForCreate.Rating = CalculateRating.CreateRating(addOffer);
and entire called class :
public class CalculateRating
{
private readonly DataContext mainContext;
public CalculateRating(DataContext mainContext)
{
this.mainContext = mainContext;
}
// calcul rating oferte noi
public decimal CreateRating(OfferForCreate offer)
{
decimal rating = mainContext.Database.FromSql<decimal>("RatingCalculator", offer.locationId, offer.typeId);
return rating;
}
}
I get an error when try to execute this procedure:
Error CS1061: 'DatabaseFacade' does not contain a definition for 'FromSql' and no extension method 'FromSql' accepting a first argument of type 'DatabaseFacade' could be found
and another if I don't create an instance of CalculateRating class in my controller :
Controllers\AnnouncesController.cs(127,37): error CS0120: An object reference is required for the non-static field, method, or property 'CalculateRating.CreateRating(OfferForCreate)
Everywhere I see must specify the entity, but what entity I can specify if my stored procedure use multiple tables?
Asp.Net Core Web API
You can execute stored proc like this:
using (var command = mainContext.Database.GetDbConnection().CreateCommand())
{
command.CommandType = System.Data.CommandType.StoredProcedure;
command.CommandText = "dbo.RatingCalculator";
var locationIdParam = new System.Data.SqlClient.SqlParameter("#locationId", System.Data.SqlDbType.Int);
locationIdParam .Value = offer.locationId;
//DO same for typeId parameter
//Params to Parameters collection
command.Parameters.Add(locationIdParam);
command.Connection.Open();
return (double)command.ExecuteScalar();
}
Controllers\AnnouncesController.cs(127,37): error CS0120: An object reference is required for the non-static field, method, or property 'CalculateRating.CreateRating(OfferForCreate)
This error is occuring because if you declare CalculateRating as static you can not reference in non-static field mainContext.
You should create an instance of your CalculateRating class using Dependency Injection. Here are steps:
Create an interface ICalculateRating
public interface ICalculateRating {
decimal CreateRating(OfferForCreate offer);
}
Update CalculateRating class to implement ICalculateRating
Register the DBContext and ICalculateRating mappings in ConfigureServices method of Startup.cs file like this:
services.AddDbContext<DbContext>(opts=> { opts.UseSqlServer("sqlserver conntection string") }, ServiceLifetime.Scoped);
services.AddTransient<ICalculateRating, CalculateRating>();
In your controller constructor, input an argument of type ICalculateRating which will be injected by Microsoft Dependency Injection framework at runtime:
private readonly ICalculateRating _calculateRating;
public MyController(ICalculateRating calculateRating) {
_calculateRating = calculateRating;
}
You can then call the method like this:
offerForCreate.Rating = _calculateRating.CreateRating(addOffer);

Entity Framework and DetailsView in N-Tier Application

I am absolutely new to Entity Framework so please don't hesitate to point any errors. Anyway I'll try to describe my problem as I understand it.
I am creating a n-Tier application with Entity Framework. I am also using a generic repository as described in this page.
I was successful in populating a DetailsView and inserting a value to the database through an ObjectDataSource. However the problem I am encountering occurs when I am updating.
The error that I get is
An object with a key that matches the key of the supplied object could
not be found in the ObjectStateManager. Verify that the key values of
the supplied object match the key values of the object to which
changes must be applied.
And I understand WHY it happens as well. I use the following methods to populate the values from the DB.
public IEnumerable<TEntity> GetAll<TEntity>() where TEntity : class
{
return GetQuery<TEntity>().AsEnumerable();
}
public List<Company> GetAllCompanies()
{
return _genericRepository.GetAll<Company>().ToList();
}
If I put a breakpoint in the GetAll method and observe the results I see that anEntityKey is set and IsChangeTracked is true for each object in the list.
But if I check the object passed to the UpdateMethod specified for the ObjectDataSource, then EntityKey is null, EntityState is detached and IsChangeTracked is false. So because the EntityKey is null, I understand the exception is valid.
My update method looks like
public void Update<TEntity>(TEntity entity) where TEntity : class
{
ObjectSet<TEntity> objSet = DataContext.CreateObjectSet<TEntity>();
objSet.ApplyCurrentValues(entity);
SaveChanges();
}
I tried to attach using objSet.Attach(entity); then no exceptions but the object does not get updated either.
How do I properly perform the update using DetailsView ? Or how do I properly bind an ObjectDataSource to a DetailsView? How do I make sure that my EntityKey does not become null ?
Solved the issue using the method shown below
public void Update<TEntity>(TEntity entity) where TEntity : class
{
object originalItem;
EntityKey key = DataContext.CreateEntityKey(GetEntityName<TEntity>(), entity);
if (DataContext.TryGetObjectByKey(key, out originalItem))
{
DataContext.ApplyCurrentValues(key.EntitySetName, entity);
}
SaveChanges();
}

Adding custom property to Client Side Entity class

I need to add a custom property to an Entity Framework class, however when I do I get the "The property name XXX specified for type XXX is not valid." error. Is there some attribute I can give the property so it is ignored and not mapped to anything?
Edit: If I add a custom property, as per Martin's example below, then the following code will raise the above error at the SaveChanges call.
MyEntities svc = new MyEntities(url);
MyEntity ent = new MyEntity();
ent.MyField = "Hello, world";
svc.AddMyEntity(ent);
svc.SaveChanges();
You can add a property in code:
public partial class MyEntity {
public String MyCustomProperty {
get;
set;
}
}
The Entity Framework generate partial classes enabling you to customize the generated class.
Also, to comment on your code I think should change it to something like this:
MyEntities svc = new MyEntities(url);
// Create MyEntity using the factory method.
MyEntity ent = MyEntities.CreateMyEntity(...);
ent.MyField = "Hello, world";
svc.AddMyEntity(ent);
svc.SaveChanges();
This will ensure that your entity is properly initialized.
Here is the answer:
http://social.msdn.microsoft.com/Forums/en-US/adodotnetdataservices/thread/b7a9e01d-c5c2-4478-8f01-00f7f6e0f75f
Edit:
A better link describes the final compact answer of Adding an Attribute to prevent serialization of the Entity when sending to the Service.