how to desactivate lazy loading for entity framework 6 - asp.net-mvc-5

public class Country : Item
{
public string Code
{get; set;}
public string CodePhone
{ get; set; }
public string Name
{get; set;}
public string Flag
{ get; set; }
public decimal? Latitude
{get; set;}
public decimal? Longitude
{get; set;}
public int RegionsCount
{get; set;}
[ForeignKey("DefaultCurrency")]
public int? DefaultCurrencyID
{get; set;}
public virtual Currency DefaultCurrency
{ get; set; }
public ContinentType ContinentType
{ get; set; }
public virtual ICollection<Property>
Properties
{get; set;}
public ICollection<CountryLocale>
CountryLocales
{ get; set; }
}
public class CountryLocale : ItemLocale
{
[ForeignKey("Country")]
public int CountryID
{get; set;}
public Country
Country
{get; set;}
public string FullName
{get;set;}
}
public TEntity Get(Expression<Func<TEntity, bool>> where, params string[] includes)
{
var model = this.DbSet;
foreach (var property in includes)
{
model.AsExpandable().Include(property);
}
return model.Where(where).FirstOrDefault();
}
this.Configuration.LazyLoadingEnabled = false;
this.Configuration.ProxyCreationEnabled = false;
Country country = this._CountryRepository.Get(p=>p.ID == this.CountryID, new string[] { "CountryLocales" });
Value cannot be null.
Parameter name: source
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
Exception Details: System.ArgumentNullException: Value cannot be null.
Parameter name: source
line : CountryLocale countrylo = country.CountryLocales.First();
i got this error when trying to desactivate lazyloading for performance reasons. how can i resolve the problem? thanks in advance.

As you disabled LazyLoading you need to manually load the child properties of your main object with Include
var country = db.Country.Include("CountryLocales");
The other way around would be:
Dont disable lazy load and use include in your queries.
Try including your child objects one by one until you feel the
performance is better.
Usually if you know you will iterate over a
child object you should use include in your query for that child
object.
remeber to include second level child if you need to access a property of that level... Include("Parent.Child")

Related

Automapper projection results in empty collection for nested Dto

I have a .Net Core 2 webapi in which I am using automapper to map to Dtos. Everything works fine, except I am seeing an unexpected behaviour when I map an object to a Dto, and where the Dto also contains mappings for a collection. E.g
CreateMap<Order, OrderDto>();
CreateMap<Product, ProductDto>();
Where classes are like this
public partial class Order
{
public int Id { get; set; }
public string Name { get; set; }
public virtual ICollection<Product> Products{ get; set; }
public int ProductCount {return Products.Count;}
}
public partial class Product
{
public int Id { get; set; }
public int OrderId { get; set; }
public string Name { get; set; }
public string Description { get; set; }
}
The following works as expected;
The class is mapped, and the ProjectCount is correct in the Dto
public partial class OrderDto
{
public int Id { get; set; }
public virtual ICollection<Product> Products{ get; set; }
public int ProductCount{ get; set; }
}
_context.Orders.Include<>(Products).ProjectTo<>(OrderDto)
But doing the following, the productcount is always zero.
E.g. if I do this;
public partial class OrderDto
{
public int Id { get; set; }
public virtual ICollection<ProductDto> Products{ get; set; }
public int ProductCount{ get; set; }
}
public partial class ProductDto
{
public int Id { get; set; }
public int OrderId { get; set; }
public string Name { get; set; }
}
_context.Orders.Include<>(Products).ProjectTo<>(OrderDto)
Why does this happen, and how can I ensure that it doesnt? This is a real world example where I need a property which references the collection - and I need it in both the base and the Dto. I can do the following which works fine, but it doesnt appear that this should be how it works...
public partial class OrderDto
{
public int Id { get; set; }
public virtual ICollection<ProductDto> Products{ get; set; }
public int ProductCount {return Products.Count;}
}
public partial class ProductDto
{
public int Id { get; set; }
public string Name { get; set; }
}
_context.Orders.Include<>(Products).ProjectTo<>(OrderDto)
I profiled the SQL and found that Automapper changes the way the query is formed. Without the nested projection, two queries are made;
[Queries are more complex than this and use joins, but you get the idea]
Select Id from orders
Select Id,Name from products where productid in [select id from orders ]
With the nested projection, are executed for each nested Dto
Select Id from orders
Select Id,Name from products where id=1
Select Id,Name from products where id=2

LinqToExcel - InvalidCastException leading to Object must implement Iconvertible error

I'm using the following code to query an excel file in LinqToExcel:
var excelFile = new LinqToExcel.ExcelQueryFactory(#"\"+txtFileName.Text.Replace(#"\\",#"\"));
var properties = from p in excelFile.Worksheet<Property>()
where AssessmentID != null
select p;
foreach (var autoP in properties)
doSomething();
When I look at the runtime debugger, I see an "InvalidCastException" while looking at the "Results View" of the properties variable. So, I'm assuming that there's something funky going on with my class definition. I'm also assuming that I don't need to map all members of the class to the excel file, but rather only the ones I see fit.
So, Here's the class definition as well:
public class Property
{
[DataMember]
public int? Year { get; set; }
[DataMember]
public string ChangeReason { get; set; }
[DataMember]
public string AssessmentID { get; set; }
[DataMember]
public string CallBackNotes { get; set; }
[DataMember]
public string InspectionNotes { get; set; }
[DataMember]
public string Notes { get; set; }
[DataMember]
public bool Authorization { get; set; }
[DataMember]
public string ChargeStatus { get; set; }
[DataMember]
public string LegalLandDesc { get; set; }
[DataMember]
public string Address { get; set; }
}
Here's a link to the source code for linqToExcel on GitHub:LinqToExcel
The generics are more complicated than I've seen, and are something that I (apparently) need to brush up on.
Is there something glaring that I'm missing that would cause this issue? Any ideas as to where to look or what to do to resolve these errors?
The where clause of the query is what was causing the error. It was referencing the null keyword which was not applicable in the context.
I changed it to:
where !String.IsNullOrEmpty(p.AssessmentID)
This solved my issue.
Note to self: When inheriting code from others, check the basics first!

automaticly serialize object via web service

I have my webservice method which sends an object as a result, for example:
public Dog GetDog();
where dog looks like this:
public class Dog{
public string Name { get; set;}
public int Age{ get; set;}
}
Is there any way how to set the default serialization method without having to change the method to:
public string GetDog(){
return dog.toString();
}
thanks
Assuming you are talking about .net web services. Here is the trick.
[WebMethod]
public Dog GetDog()
{
//method code
}
[System.Xml.Serialization.XmlTypeAttribute(Namespace="http://tempuri.org/")]
public class Dog{
public string Name { get; set;}
public int Age{ get; set;}
}
You can read this article for further understanding.
http://ryanfarley.com/blog/archive/2004/05/26/737.aspx

Subsonic 3 - Simple repository and creating a foreign key

There seems to be hardly any examples out there so here goes:
Here are my three structures but it doesn't seem to create the tables properly and when I call the following line it says Id is not recognised:
IEnumerable<Permission> permissions = _data.Find<RolePermission>(x => x.Role.RoleKey == roleKey).Select(x => x.Permission);
RolePermission:
public class RolePermission
{
[SubSonicPrimaryKey]
public int RolePermissionId { get; set; }
public int RoleId { get; set; }
public int PermissionId { get; set; }
//Foreign Key of Role
public Role Role { get; set; }
//Foreign key of Permission
public Permission Permission { get; set; }
}
Permission:
public class Permission
{
[SubSonicPrimaryKey]
public int Id { get; set; }
[SubSonicLongString]
public string PermissionKey { get; set; }
[SubSonicLongString]
public string PermissionDescription { get; set; }
}
Role:
public class Role
{
[SubSonicPrimaryKey]
public int Id { get; set; }
[SubSonicLongString]
public string RoleKey { get; set; }
[SubSonicLongString]
public string RoleDescription { get; set; }
}
I don't know if this has been fixed in a current release but I remember a silly bug in subsonic's primary key detection.
If your Object contains a property named Id subsonic assumes that is your primary key.
If not you have to tell subsonic with is your PK by decorating a property with the SubSonicPrimaryKey attribute (like you did).
If you have a property called Id and it is also decorated with the attribute (like your Role and Permission class) subsonic finds the property twice and does not check if they both equals. Then it throws an exception because it can't reliably determine which one to take.
Long story short, you should try:
a) Remove the Attribute from your Id column
b) Rename the property to RoleId or PermissionId (which would be more consistend because your RolePermission class has it's PK called RolePermissionId)
If that doesn't help, please provide a stacktrace.

How do you exclude a property from being persisted in Azure Table storage?

If I have a class like this:
public class Facet : TableServiceEntity
{
public Guid ParentId { get; set; }
public string Name { get; set; }
public string Uri{ get; set; }
public Facet Parent { get; set; }
}
Parent is derived from the ParentId Guid, and that relationship is intended to be filled in by my repository. So how do I tell Azure to leave that field alone? Is there an Ignore attribute of some type, or do I have to create an inherited class that provides those relationships instead?
Using latest Microsoft.WindowsAzure.Storage SDK (v6.2.0 and up), the attribute name has changed to IgnorePropertyAttribute :
public class MyEntity : TableEntity
{
public string MyProperty { get; set; }
[IgnoreProperty]
public string MyIgnoredProperty { get; set; }
}
There is an attribute called WindowsAzure.Table.Attributes.IgnoreAttribute can be set on the property you want to exclude. Just use:
[Ignore]
public string MyProperty { get; set; }
It is a part of Windows Azure Storage Extensions, which you may download from:
https://github.com/dtretyakov/WindowsAzure
or install as a package:
https://www.nuget.org/packages/WindowsAzure.StorageExtensions/
The library is MIT licensed.
This reply from Andy Cross at bwc --- Thank you again Andy.
This question an azure forums
Hi,
Use the WritingEntity and ReadingEntity events. http://msdn.microsoft.com/en-us/library/system.data.services.client.dataservicecontext.writingentity.aspx This gives you all the control you need.
For reference there's a blog post linked off here too: http://social.msdn.microsoft.com/Forums/en-US/windowsazure/thread/d9144bb5-d8bb-4e42-a478-58addebfc3c8
Thanks
Andy
You may override the WriteEntity method in TableEntity and remove any properties that have your custom attribute.
public class CustomTableEntity : TableEntity
{
public override IDictionary<string, EntityProperty> WriteEntity(Microsoft.WindowsAzure.Storage.OperationContext operationContext)
{
var entityProperties = base.WriteEntity(operationContext);
var objectProperties = GetType().GetProperties();
foreach (var property in from property in objectProperties
let nonSerializedAttributes = property.GetCustomAttributes(typeof(NonSerializedOnAzureAttribute), false)
where nonSerializedAttributes.Length > 0
select property)
{
entityProperties.Remove(property.Name);
}
return entityProperties;
}
}
[AttributeUsage(AttributeTargets.Property)]
public class NonSerializedOnAzureAttribute : Attribute
{
}
usage
public class MyEntity : CustomTableEntity
{
public string MyProperty { get; set; }
[NonSerializedOnAzure]
public string MyIgnoredProperty { get; set; }
}
You could also make the getter and setter non-public in order to skip the property from being saved in the table storage database.
See: https://stackoverflow.com/a/21071796/5714633

Resources