I have an object
public partial class FileAttachment
{
public FileAttachment()
{
this.Tags = new HashSet<Tag>();
}
public virtual ICollection<Tag> Tags {get; set;}
...other propertties
}
My context class is having
public virtual DbSet<FileAttachment> FileAtttachments {get; set;}
public virtual DbSet<Tag> Tags {get; set;}
public virtual DbSet<Item> Items {get; set;}
...
I am using it in my controller like
MyContext.Items.AsNoTracking().Where(i => i.ItemId == inputId &&
MyContext.FileAttachments.AsNoTracking.Where(f => f.RecordId == i.ReferenceId && f.RecordType == 'item').Any()).Any();
The error I am getting is
'Method 'System.Data.Entity.Infrastructure.DbQuery1[Demo.FileAttachment] AsNoTracking()' declared on type 'System.Data.Entity.Infrastructure.DbQuery1[Demo.FileAttachment]' cannot be called with instance of type 'System.Data.Entity.Core.Objects.ObjectQuery`1[Demo.FileAttachment]''
I am new to AsNoTracking(). Anyone can tell where I am doing wrong?
CodePudding user response:
It looks like the actual requirement is to check whether an Item with a specific ID has a related FileAttachment of a specific type. There's no need for AsNoTracking() for this since the query returns a single boolean, not objects that need tracking.
If the classes had proper navigation properties, the query would be a simple:
var found= MyContext.FileAttachments.Any(f=>f.RecordType == 'item'
&& f.Item.Id = ThatItemID);
Without them, the LINQ query will have to JOIN the two "unrelated" entities:
var query = from item in MyContext.Items
join person in MyContext.FileAttachmentes
on file.RecordId equals item.ReferenceId
where item.ItemID == ThatId &&
file.RecordType == 'item'
select 1;
var found=query.Any();
The lack of navigation properties is a very strong sign that the model is wrong though.
A DbContext isn't a model of the database and doesn't have to mirror it. There's no need to have a single DbContext for the entire application either. Even if there are no Foreign Key Constraints between Items and FileAttachments it's possible to add relations between the classes
CodePudding user response:
AsNoTracking() is used to prevent entity tracking by EF. Tracking allows EF to keep track of modifications made and on saving, these changes can be persisted. So, if a query doesn't need tracking (like a simple get query where no data change is persisted), we use AsNoTracking().
In your case, use navigation property if the entities are related instead of calling Context.Entity. Also, AsNoTracking() needs to specified only once in the query before loading the data.
