I have the following EF class:
class Product
{
public Guid ProductGuid { get; set; }
public string ProductName { get; set; }
}
derived from a DB class where ProductGuid is a uniqueidentifier and ProductName is a nvarchar.
Consider productContext as the context:
var products = productContext.Products;
productList = products.ToList();
OR
productList = products.AsEnumerable();
The first instruction is executed correctly the second (both) launches an exception at runtime (it compiles correctly):
Unable to cast the type 'System.Guid' to type 'System.Object'. LINQ to
Entities only supports casting Entity Data Model primitive types.
I tried everything it does not work. I have other tables with Guid field but it never launches such exception. What can be the cause?
Do you really need to use the GUID type in that property? Wouldn't string do it for you anyway?
try replacing GUID. use String instead.
Related
Hi my Entity is ParameterDetail as follows:
public class ParameterDetail
{
[Key]
public int Id { get; set; }
public string Name { get; set; }
[NotMapped]
public string Description { get; set; }
//..other columns removed for brevity
public int LookupValueId { get; set; }
}
I call my stored procedure and load the results as follows...
List<ParameterDetail> paramDetails = this.ParameterDetails.FromSqlRaw("EXEC dbo.GE_GetStartParameter #GuidelineName={0}", guidelineName).ToList();
Now this all is working fine but now I have to call a slightly different procedure which does not have LookupValueId..
List<ParameterDetail> paramDetails =this.ParameterDetails.FromSqlRaw("EXEC dbo.GetParameterDetails #ParameterId={0}", nextParam).ToList();
I don't want to add another EntityModel just for this one column....
Can i use Mapped property (Data Annotation) at runtime somehow? Or could there be any other solution?
Can i use Mapped property (Data Annotation) at runtime somehow? Or could there be any other solution?
Not if you want EF to perform the mapping, at least not a good one. You can't change the attributes at runtime, but if you use Fluent configuration you could have two different DbContext subtypes that configure the same entity class differently. But that's not a very elegant solution.
You can always just execute the stored procedure with ADO.NET and map the data however you want.
My database has a table like this:
Cats
- CatId INT PK
- Name VARCHAR(100)
- FavoriteToy VARCHAR(100)
And my code looks like this:
Cat.cs
public int CatId { get; set; }
public string Name { get; set; }
public Toy FavoriteToy {get; set; }
StaticVariables.cs
public enum Toy { Box, Ball, StuffedAnimal }
In a normalized database I would use a lookup table in the database to store all the toys and then the Cats table would just store a ToyId. But for this situation it's a lot easier to just store the FavoriteToy as a string even though it will be redundant.
The problem is I don't know how to convert a string in the database to an enum in code without creating a second FavoriteToyString property and having FavoriteToy just be a computed that returns the enum derived from FavoriteToyString.
I've heard this might be possible in the current version of entity framework. Is that true? Can you please show me how to do this?
You may use DTO class and automapper to solve your issue :)
Generally, yes a lookup table reference is a better option since your data can comply with referential integrity. That is, No cat records with toys that your Enum hopefully doesn't contain. (Though your Enum would need to be kept in sync with the Toys table.) You can configure EF to store enumerations as a string using a bit of a trick with the mapping:
public class Cat
{
[Key]
public int CatId { get; set; }
public string Name { get; set; }
[Column("FavoriteToy")]
public string FavoriteToyMapped { get; set; }
[NotMapped]
public Toy FavoriteToy
{
get { return (Toy)Enum.Parse(typeof(Toy), FavoriteToyMapped); }
set { FavoriteToyMapped = value.ToString(); }
}
}
The caveat of this approach is that where you might use Linq to Entity to filter on your cat's favorite toy, you need to reference the FavoriteToyMapped value in the query expression because EF/DB won't know what FavoriteToy is.
I.e.
Cats with a favorite toy of "Yarn"
var catsThatLoveYarn = context.Cats.Where(c => c.FavoriteToyMapped == Toys.Yarn.ToString()).ToList();
// not
var catsThatLoveYarn = context.Cats.Where(c => c.FavoriteToy == Toys.Yarn).ToList();
// Will error because EF doesn't map that property.
Once you are working with instances of entities, that the set of entities has been pulled back from the database, you can further access/refine queries with FavoriteToy. Just be cautious and prepared for the unknown field if you use it too early and EF goes and tries to compose a query.
var threeYearOldCats = context.Cats.Where(c => c.Age == 3).ToList();
var threeYearOldCatsThatLoveYarn = threeYearOldCats.Where(c => c.FavoriteToy == Toys.Yarn).ToList();
This is Ok because the .ToList() in the first query executed the EF-to-SQL, so threeYearOldCats is now a local List<Cat> of cat entities, not an IQueryable<Cat>.
I have a problem with an EF6 and LINQ to Entities method inasmuch as I cannot cast from one class, Claim, to a derived class, ClaimDetail. I am certain that this cast would be valid but I don't know fiddle with the syntax to get the cast to work.
The relevant portions of the model look like this:
// Claim.cs
public class Claim
{
public int Id { get; set; }
// ..other properties
}
and
// ClaimDetail.cs
public class ClaimDetail : Claim
{
public string ClaimRef { get; set; }
// ..other properties
}
I have another class, Request, that looks like this:
// Request.cs
public class Request
{
public Claim Claim { get; set; }
// ..other properties
}
These classes form a part of the context, like this:
// Context.cs
public DbSet<ClaimDetail> Claims { get; set; }
public DbSet<Request> Requests { get; set; }
Now, I would like to sort a LINQ query of Requests based on a property of ClaimDetail. I have this:
sorted = intermediate.OrderBy(r => ((ClaimDetail)r.Claim).ClaimRef);
where intermediate is an IQueryable<Request>. However, on trying to materialize this query, I receive the following message:
Unable to cast the type 'Claim' to type 'ClaimDetail'. LINQ to Entities only supports casting EDM primitive or enumeration types.
How can I do this, without resorting to calling ToList() on the intermediate results? That would be far too expensive.
I want to create a TimeStamp field in Inherited class like this:
[Table("TABLE_A")]
public class A
{
public int ID {get;set;}
public string Name {get;set;}
}
[Table("TABLE_B")]
public class B : A
{
public string Address {get;set;}
[TimeStamp]
public byte[] RowVersion {get;set;}
}
but failed, how can I do here ?
You will see error
Type 'B' defines new concurrency requirements that are not allowed for
subtypes of base EntitySet types.
That means exactly what error says. Entity Framework do not support concurrency checks in derived types. You will see same error if you'll add simple concurrency check instead of timestamp:
[Table("TABLE_B")]
public class B : A
{
[ConcurrencyCheck]
public string Address { get; set; }
}
If you will move concurrency checking to base class, then it will work, but only on base type. If you need checking to be performed on derived type, I think you should use Stored Procedure for updating entity.
I want to define [Required] attributes on a Complex Type in Entity Framework. For example, I have a Customer entity with an optional Address. The Address entity has a required PostCode property.
[ComplexType]
public class Address {
public string Address1 { get; set; }
[Required]
public string PostCode { get; set; }
}
public class Customer {
public int CustomerId {get;set;}
public Address Address {get;set;}
}
I do NOT want to store my Complex type as a separate entity (I'm not actually using Address, this just an easy illustration of the problem). I cannot leave Customer.Address null, because this gives the error:
Null value for non-nullable member. Member: 'Address'.
If I supply an empty Address entity, the validation fails on the PostCode field because of the Required attribute.
Is there any way to achieve this? I'm using EF5/NET4.5.
It's not possible with a complex type. You'll need to create an Address entity if you want it to be nullable.
What EF will do with a complex type is map the properties to the same table - which it sounds like you've intended.
Because of that - your schema for your example would look like this:
With a non-nullable column for Address_PostCode, since it's not valid in the database there's not a way for EF to create the row, without your object having an address, and a postcode.