I am trying to update a many to many relationship that I have setup in Entity Framework using Code First. I've created the following Models.
[Serializable]
public class ClientFormField : FormField
{
public ClientFormField()
{
CanDisable = true;
}
public virtual ClientFormGroup Group { get; set; }
public virtual ICollection<ClientValue> Values { get; set; }
public virtual ICollection<LetterTemplate> LetterTemplates { get; set; }
}
[Serializable]
public class CaseFormField : FormField
{
public CaseFormField()
{
CanDisable = true;
}
public virtual CaseFormGroup Group { get; set; }
public virtual ICollection<LetterTemplate> LetterTemplates { get; set; }
public override IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
foreach (var val in base.Validate(validationContext))
yield return val;
}
}
[Serializable]
public class SystemField : TrackableEntity
{
public string Name { get; set; }
public string Value { get; set; }
public string VarName { get; set; }
public virtual SystemFieldType SystemFieldType { get; set; }
public int TypeId { get; set; }
public ICollection<LetterTemplate> LetterTemplates { get; set; }
public override IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
if (string.IsNullOrWhiteSpace(Name))
yield return new ValidationResult("System field must have a name.", new[] { "SystemFieldName" });
if (string.IsNullOrWhiteSpace(Value))
yield return new ValidationResult("System field must have a value.", new[] { "SystemFieldValue" });
var regex = new Regex(#"^[a-zA-Z0-9-_]+$");
if (!string.IsNullOrWhiteSpace(VarName) && !regex.IsMatch(VarName))
yield return
new ValidationResult("Varname can only contain alphanumeric, underscore, or hyphen",
new[] { "SystemFieldVarName" });
if (TypeId <= 0)
yield return new ValidationResult("System Field must have a type.", new[] { "SystemFieldType" });
}
}
[Serializable]
public class LetterTemplate : TrackableEntity
{
public LetterTemplate()
{
ClientFields = new Collection<ClientFormField>();
CaseFields = new Collection<CaseFormField>();
SystemFields = new Collection<SystemField>();
}
public string Name { get; set; }
public string Data { get; set; }
public virtual ICollection<ClientFormField> ClientFields { get; set; }
public virtual ICollection<CaseFormField> CaseFields { get; set; }
public virtual ICollection<SystemField> SystemFields { get; set; }
public override IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
if(string.IsNullOrWhiteSpace(Name))
yield return new ValidationResult("Form Template must have a name", new[] { "Name" });
if(string.IsNullOrWhiteSpace(Data))
yield return new ValidationResult("Form Template must have content", new[] { "Data" });
}
}
Below is the configuration for the LetterTemplate class.
public class LetterTemplateConfiguration : BaseTrackableEntityConfiguration<LetterTemplate>
{
public LetterTemplateConfiguration()
{
HasMany(c => c.ClientFields).WithMany(c => c.LetterTemplates)
.Map(m =>
{
m.MapLeftKey("LetterTemplateId");
m.MapRightKey("ClientFormFieldId");
m.ToTable("LetterTemplateClientFields");
});
HasMany(c => c.CaseFields).WithMany(c => c.LetterTemplates)
.Map(m =>
{
m.MapLeftKey("LetterTemplateId");
m.MapRightKey("CaseFormFieldId");
m.ToTable("LetterTemplateCaseFields");
});
HasMany(c => c.SystemFields).WithMany(c => c.LetterTemplates)
.Map(m =>
{
m.MapLeftKey("LetterTemplateId");
m.MapRightKey("SystemFieldId");
m.ToTable("LetterTemplateSystemFields");
});
}
}
Here is the controller method for Add/Update and the server method that holds the business logic for Add/Update
[HttpPost]
[ValidateAntiForgeryToken]
[ValidateInput(false)]
public ActionResult Manage(LetterTemplate template)
{
if(ModelState.IsValid)
{
if (_letterTemplateService.Save(template) != null)
return RedirectToAction("List");
}
ViewBag.ClientFields = _clientFieldService.GetAllFields().OrderBy(f => f.Name);
ViewBag.CaseFields = _caseFieldService.GetAllFields().OrderBy(f => f.Name);
ViewBag.SystemFields = _systemFieldService.GetAllFields().OrderBy(f => f.Name);
return View(template);
}
public LetterTemplate Save(LetterTemplate template)
{
var dbTemplate = template;
if (template.Id > 0)
{
dbTemplate = _letterTemplateRepo.GetById(template.Id);
dbTemplate.Name = template.Name;
dbTemplate.Data = template.Data;
}
dbTemplate.ClientFields.Clear();
foreach (var field in _clientFieldRepo.All().Where(field => template.Data.Contains("~~" + field.VarName + "~~")))
dbTemplate.ClientFields.Add(field);
dbTemplate.CaseFields.Clear();
foreach (var field in _caseFieldRepo.All().Where(field => template.Data.Contains("~~" + field.VarName + "~~")))
dbTemplate.CaseFields.Add(field);
dbTemplate.SystemFields.Clear();
foreach (var field in _systemFieldRepo.All().Where(field => template.Data.Contains("~~" + field.VarName + "~~")))
dbTemplate.SystemFields.Add(field);
return template.Id <= 0 ? _letterTemplateRepo.Add(dbTemplate) : _letterTemplateRepo.Update(dbTemplate);
}
Here is the view for Add/Update of the Letter Template.
#section RightContent
{
<h4>Manage</h4>
<form method="POST" action="/LetterTemplate/Manage" id="templateForm">
<div id="toolbar">
<div style="float: left;padding: 3px 0px 0px 10px;">
#Html.LabelFor(m => m.Name)
#Html.TextBoxFor(m => m.Name)
</div>
<div class="item" onclick=" $('#templateForm').submit(); ">
<span class="save"></span>Save
</div>
<div class="item" onclick=" window.location = '/LetterTemplate/List'; ">
<span class="list"></span>Back To List
</div>
</div>
<div class="formErrors">
#Html.ValidationSummary()
</div>
#Html.HiddenFor(m => m.Id)
#Html.HiddenFor(m => m.Active)
#Html.HiddenFor(m => m.IsDeleted)
#Html.TextAreaFor(m => m.Data)
#Html.AntiForgeryToken()
</form>
}
When I am creating a new template from the view everything is working fine. I get fields populated in my Many to Many relationship tables as I expect. When I attempt to update the relationship which should clear out all existing relations and create new relations nothing happens. The tables are not affected at all. I've read through several different posts about issues with updating many to many tables but haven't found anything that fixes my issue. The is the first time I have attempted many to many with EF code first and followed many tutorials before hand but it seems that no matter what I do, EF will not update the relationship tables.
UPDATE:
Queries generated when adding a new template:
DECLARE #0 nvarchar = N'Test',
#1 nvarchar = N'<p>~~case_desc~~</p>
<p>~~fname~~</p>
<p>~~lname~~</p>
',
#2 bit = 1,
#3 bit = 0,
#4 int = 2,
#5 int = 2,
#6 DateTime2 = '2013-04-08T16:36:09',
#7 DateTime2 = '2013-04-08T16:36:09'
insert [dbo].[LetterTemplates]([Name], [Data], [Active], [IsDeleted], [CreatedById], [ModifiedById], [DateCreated], [DateModified])
values (#0, #1, #2, #3, #4, #5, #6, #7)
DECLARE #0 int = 2,
#1 int = 1
insert [dbo].[LetterTemplateClientFields]([LetterTemplateId], [ClientFormFieldId])
values (#0, #1)
DECLARE #0 int = 2,
#1 int = 2
insert [dbo].[LetterTemplateClientFields]([LetterTemplateId], [ClientFormFieldId])
values (#0, #1)
DECLARE #0 int = 2,
#1 int = 3
insert [dbo].[LetterTemplateClientFields]([LetterTemplateId], [ClientFormFieldId])
values (#0, #1)
Query Generated on update:
DECLARE #0 nvarchar = N'Test',
#1 nvarchar = N'<p>~~case_desc~~</p>
<p> </p>
<p>~~fname~~</p>
<p> </p>
<p>~~dob~~</p>
',
#2 bit = 1,
#3 bit = 0,
#4 int = 2,
#5 int = 2,
#6 DateTime2 = '2013-04-08T16:23:12',
#7 DateTime2 = '2013-04-08T16:33:15',
#8 int = 1
update [dbo].[LetterTemplates]
set [Name] = #0, [Data] = #1, [Active] = #2, [IsDeleted] = #3, [CreatedById] = #4, [ModifiedById] = #5, [DateCreated] = #6, [DateModified] = #7
where ([Id] = #8)
UPDATE
My repository pattern has 2 base generic classes. A Base Trackable Entity Repository and a Base Repository. The base trackable entity repo handles making sure deleted items are soft deleted, getting non deleted items, and managing the createdby/modifiedby and createdDate/UpdatedDate. The base repo handles the rest of the basic CRUD operations. Below is the update method and associated methods that get called when I call update through the LetterTemplateRepository. Since this repo inherits the base trackable entity repo it runs update from the base class.
public override T Update(T entity)
{
return Update(entity, false);
}
public override T Update(T entity, bool attachOnly)
{
InsertTeData(ref entity);
entity.ModifiedById = CurrentUserId;
entity.DateModified = DateTime.Now;
_teDB.Attach(entity);
_db.SetModified(entity);
if (!attachOnly) _db.Commit();
return entity;
}
private void InsertTeData(ref T entity)
{
if (entity == null || entity == null) return;
var dbEntity = GetById(entity.Id);
if (dbEntity == null) return;
_db.Detach(dbEntity);
entity.CreatedById = dbEntity.CreatedById;
entity.DateCreated = dbEntity.DateCreated;
entity.ModifiedById = dbEntity.ModifiedById;
entity.DateModified = dbEntity.DateModified;
}
The SetModified method in by DbContext just sets the EntityState to Modified. I use a Fake DbContext and DbSet in my unit tests so any EF specific calls I extend through the DbContext to allow my tests to work without having to create a bunch of Fake Repositories.
Turns out the issue was in the InsertTeData Method. When it was detaching the entity that I pulled from the db to make sure createdby and created date it caused the entity I was working with to lose all information about the many to many relationships. My guessing is the way the entity tracking works and they both had the same key.
I've removed the InsertTeData method and now manage everything as default values in the constructor of the abstract TrackableEntity class and everything is working now.
public override T Update(T entity, bool attachOnly)
{
entity.ModifiedById = CurrentUserId;
entity.DateModified = DateTime.Now;
_teDB.Attach(entity);
_db.SetModified(entity);
if (!attachOnly) _db.Commit();
return entity;
}
After running all my unit tests, integration tests, and some manual tests, everything passed so I am fine with this change.
Related
Is this possible in AutoMapper?
Select list of type X and filter child entity of type Y (return single value of Y)
ProjectTo to a flat DTO contains props from X and Y.
If it is not, then what is the best way to populate the DTO in this scenario, the tables are just for example, in the real scenario the tables have a lot of columns and I want to avoid reading the whole row just to get one or two props.
Below is a quick console App code in .Net 5.0
Project.csproj
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net5.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="AutoMapper.Extensions.Microsoft.DependencyInjection" Version="11.0.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="5.0.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore.InMemory" Version="5.0.0" />
</ItemGroup>
</Project>
Console App Testing Code
using System;
using System.Linq;
using AutoMapper;
using AutoMapper.QueryableExtensions;
using Microsoft.EntityFrameworkCore;
using System.Collections.Generic;
namespace MappingTest
{
public class Parent
{
public int Id { get; set; }
public string ParentName { get; set; }
public List<Child> Children { get; set; } = new List<Child>();
}
public class Child
{
public int Id { get; set; }
public int Age { get; set; }
public string ChildName { get; set; }
public Parent Parent { get; set; }
}
public class ParentDto
{
public int Id { get; set; }
public string ParentName { get; set; }
public string ChildName { get; set; }
}
public class DataContext : DbContext
{
public DbSet<Parent> Parents { get; set; }
public DbSet<Child> Children { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseInMemoryDatabase("MyDb");
}
}
internal class Program
{
public static void Seed(DataContext context)
{
context.Parents.Add(new Parent
{
Id = 1,
ParentName = "John",
Children = new List<Child>()
{
new Child { Id = 1, ChildName = "Peter", Age = 10 },
new Child { Id = 2, ChildName = "Smith", Age = 20 }
}
});
context.Parents.Add(new Parent
{
Id = 2,
ParentName = "Micheal",
Children = new List<Child>()
{
new Child { Id = 3, ChildName = "Wale", Age = 10 },
new Child { Id = 4, ChildName = "Robert", Age = 25 }
}
});
context.SaveChanges();
}
static void Main(string[] args)
{
var config = new MapperConfiguration((cfg) =>
{
cfg.CreateMap<Parent, ParentDto>();
cfg.CreateMap<Child, ParentDto>();
});
var mapper = config.CreateMapper();
using (var context = new DataContext())
{
Seed(context);
var parent = context.Parents
// Filter children and get only the 10 years old (Peter and Wale)
// Project to the Dto and have the ChildName mapped to the Dto
// Note: Parent should have only one 10 years old child
.ProjectTo<ParentDto>(mapper.ConfigurationProvider)
.ToList();
foreach(var p in parent)
{
Console.WriteLine(string.Format("{0} - {1} - {2}",p.Id, p.ParentName, p.ChildName));
}
}
}
}
}
Could not find a similar scenario with a solution
Update #1
I'm really considering Dapper No Mapper, #Prolog your answer helped a lot, I managed to solve it correctly by using the other way around
var config = new MapperConfiguration((cfg) =>
{
cfg.CreateMap<Parent, ParentDto>();
cfg.CreateMap<Child, ParentDto>()
.IncludeMembers(e => e.Parent);
});
And then ProjectTo like this
var parents = context.Parents
.SelectMany(e => e.Children.Where(a => a.Age == 10))
.ProjectTo<ParentDto>(mapper.ConfigurationProvider)
.ToList();
But the generated SQL is funny
SELECT [t].[ChildName], [t].[Id], [p0].[ParentName]
FROM [Parents] AS [p]
INNER JOIN (
SELECT [c].[Id], [c].[ChildName], [c].[ParentId]
FROM [Children] AS [c]
WHERE [c].[Age] = 10
) AS [t] ON [p].[Id] = [t].[ParentId]
LEFT JOIN [Parents] AS [p0] ON [t].[ParentId] = [p0].[Id]
Where the required SQL is very simple
SELECT p.Id,
p.ParentName,
c.ChildName
FROM dbo.Parents p
LEFT JOIN dbo.Children c ON p.Id = c.Id
-- or INNER JOIN
WHERE c.Age = 10;
You can use IncludeMembers() to tell AutoMapper to try to fill properties of ParentDto will values from Child after it is done with mapping from Parent. Read more about this feature in AutoMapper documentation.
var config = new MapperConfiguration((cfg) =>
{
cfg.CreateMap<Parent, ParentDto>()
.IncludeMembers(src => src.Children.First());
cfg.CreateMap<Child, ParentDto>();
});
Also, don't test your database-oriented projections with an In-Memory database, as it will hide all kind of query execution errors until you switch to a real database.
So if you want to filter out only to parents with a child that's 10 years old:
var parents = context.Parents
.Where(x => x.Children.Any(x => x.Age == 10))
.ProjectTo<ParentDto>(mapper.ConfigurationProvider)
.ToList();
with Microsoft SQL-Server, such query will be produced:
SELECT [p].[id],
[p].[parentname],
(SELECT TOP(1) [c0].[childname]
FROM [children] AS [c0]
WHERE [p].[id] = [c0].[parentid]) AS [ChildName]
FROM [parents] AS [p]
WHERE EXISTS (SELECT 1
FROM [children] AS [c]
WHERE ( [p].[id] = [c].[parentid] )
AND ( [c].[age] = 10 ))
I have a blazor component:
#inject IJSRuntime JSRuntime
#using bullDocDBAcess
#using bullDocDBAcess.Models
#inject ITagData _db
#if(tags == null){
<p><em>Loading...</em></p>
}else{
<input type="text" #bind=#tags data-role="tagsinput" />
<input type="hidden" #onchange="onChange" value=#tags />
}
#code{
private string tags = "";
private List<TagModel> tagsList;
private Task<IJSObjectReference> _module;
private Task<IJSObjectReference> Module => _module ??= JSRuntime.InvokeAsync<IJSObjectReference>("import", "./components/tagsinput/tags_inputs_imports.js").AsTask();
[Parameter]
public int organizationId { get; set; } = 0;
[Parameter]
public int documentId { get; set; } = 0;
[Parameter] public EventCallback<Notification> OnTagsChange { get; set; }
private void onChange(Microsoft.AspNetCore.Components.ChangeEventArgs args)
{
tags = (string) args.Value;
OnTagsChange.InvokeAsync(new Notification(tags, documentId.ToString()));
}
protected override async Task OnInitializedAsync()
{
if(organizationId == 0){ //inserção
tags = "";
}else{
tagsList = await _db.GetTagsFromDocument(organizationId, documentId);
foreach (TagModel t in tagsList){
if(String.IsNullOrEmpty(tags)){
tags += t.nome;
}else{
tags += "," + t.nome;
}
}
}
var module = await Module;
await module.InvokeVoidAsync("loadScripts");
}
public async ValueTask DisposeAsync()
{
if (_module != null)
{
var module = await _module;
await module.DisposeAsync();
}
}
}
Basically, the idea is to use a bootstrap input tag (called using jsinterop) and include it several times for each product in a table. When tags and updated in this table, the database should be updates with the tags for that specific values.
The parent component:
(...)
#for(int i=0;i<this.document.Count;i++)
{
DocumentModel p = this.document.ElementAt(i);
<tr>
<td><TagManagement #key=#p.id organizationId=#p.organizacao_id documentId=#p.id OnTagsChange="TagsHandler" /></td>
</tr>
}
(...)
void TagsHandler(Notification notification)
{
Console.WriteLine("Hello"); //only for testing purposes
}
A two-way binding is implemented between the parent and child. However, o have no idea how to handle multiple component invocation with callback function for each one. When a new tag is inserted, only works on the first element of the table and the event is fired two times (because in this test I only have two rows).
I tried to include the key attribute but didn't work. Can you please help me?
Best regards
I'm working in Entity Framework 5 and having problems creating an expression to use inside a method.
I believe the problem is that normally I would call the expression in a lambda expression such as dbContext.Counties.Select(GetLargeCities()), but in the code I am working with, I am projecting the Counties entity into a view model called CountyWithCities. Where I would normally call the expression, I have a singleton c and don't know how to call the expression there.
The reason I want to accomplish this using an expression is because I want the GetCountiesWithCities method to hit the database once, with Entity Framework constructing a complex graph for all the objects in the result.
For some reason the code below is producing the error `The name 'GetLargeCities' does not exist in the current context."
public class CountyWithCities // this is a view model
{
public int CountyID { get; set; }
public string CountyName { get; set; }
public IEnumerable<City> Cities { get; set; }
}
public class City // this is an entity
{
public int CityID { get; set; }
public string CityName { get; set; }
public int Population { get; set; }
}
public IEnumerable<CountyWithCities> GetCountiesWithCities(int StateID)
{
return dbContext.States
.Where(s => s.StateID = StateID)
.Select(s => s.Counties)
.Select(c => new CountyWithCities
{
CountyID = c.CountyID,
CountyName = c.CountyName,
Cities = GetLargeCities(c) // How do I call the expression here?
});
}
public Expression<Func<County, IEnumerable<City>>> GetLargeCities = county =>
county.Cities.Where(city => city.Population > 50000);
Thanks!
I normally do this with an extension method.
public static IQueriable<City> LargeCities(this IQueriable<County> counties){
return counties
.SelectMany(county=>county.Cities.Where(c=>c.Population > 50000));
}
usage:
dbContext.Counties.LargeCities()
public IEnumerable<CountyWithCities> GetCountiesWithCities(int StateID)
{
return dbContext.States
.Where(s => s.StateID = StateID)
.Select(s => s.Counties)
.LargeCities()
.GroupBy(c=>c.County)
.Select(c => new CountyWithCities
{
CountyID = g.Key.CountyID,
CountyName = g.Key.CountyName,
Cities = g.AsQueriable() // i cant remember the exact syntax here but you need the list from the group
});
}
Consider the following situation:
public class EntityA
{
public int Id { get; set; }
}
public class EntityB
{
public int Id { get; set; }
public virtual EntityA EntityA { get; set; }
}
public class Context : DbContext
{
public Context()
: base("EF_SPIKE")
{
}
public IDbSet<EntityA> EntityAs { get; set; }
public IDbSet<EntityB> EntityBs { get; set; }
}
static void Main(string[] args)
{
using (var context = new Context())
{
var a = context.EntityAs.Create();
context.EntityAs.Add(a);
var b = context.EntityBs.Create();
b.EntityA = a;
context.EntityBs.Add(b);
context.SaveChanges();
using (var transaction = new TransactionScope())
{
context.EntityBs.Remove(b);
context.SaveChanges();
}
Trace.Assert(b.EntityA == null);
Trace.Assert(context.EntityBs.Local.All(x => x.Id != b.Id));
Trace.Assert(context.EntityBs.Any(x => x.Id == b.Id));
}
}
So although the transaction is rolled back and the entity still exists in the database, the entity framework entity b no longer exists in the local cache, loses all of its foreign key references and b can no longer be worked with.
This behaviour seems odd to me since although I've rolled back, my entity is still dead.
Is there any standard workaround to this so that:
Trace.Assert(context.EntityBs.Local.Any(x => x.Id == b.Id));
passes?
I'm new with orchard.
To learn orchard module development, I am following documentation to try to create a commerce module.
The module consists of product part and product type, which has product part.
When I try to save data in following method:
public ActionResult Create(FormCollection input)
{
var product = contentManager.New<ProductPart>("Product");
product.Description = input["Description"];
product.Sku = input["Sku"];
product.Price =Convert.ToDecimal(input["Price"]);
if (!ModelState.IsValid)
{
return View(product);
}
contentManager.Create(product);
return RedirectToAction("Index");
}
I am getting an error that specific cast is Invalid and part(ContentPart) is null.
public static T New<T>(this IContentManager manager, string contentType)
where T : class, IContent {
var contentItem = manager.New(contentType);
if (contentItem == null)
return null;
var part = contentItem.Get<T>();
if (part == null)
throw new InvalidCastException();
return part;
}
I used content type Product and I have ProductRecord class for storage data, as below:
public class ProductRecord:ContentPartRecord
{
// public virtual int Id { get; set; }
public virtual string Sku { get; set; }
public virtual string Description { get; set; }
public virtual decimal Price { get; set; }
}
public class ProductPart : ContentPart<ProductRecord>
{
/*
public int Id
{
get { return Record.Id; }
set{Record.Id = value;}
}
*/
[Required]
public string Sku
{
get { return Record.Sku; }
set { Record.Sku = value; }
}
[Required]
public string Description
{
get { return Record.Description; }
set{ Record.Description = value;}
}
[Required]
public decimal Price
{
get { return Record.Price; }
set { Record.Price = value; }
}
}
Can anybody tell me what my problem is?
I'm just guessing, but did you declare your record and your ContentType in migration.cs? If you didn't, the content management will be unable to create a content item with your type as it will not know the type in question.
Your migration.cs should look somehow like that:
public class Migrations : DataMigrationImpl
{
public int Create()
{
SchemaBuilder.CreateTable("ProductRecord",
table =>
{
table.ContentPartRecord()
.Column<string>("Sku")
.Column<string>("Description")
.column<decimal>("Price");
});
ContentDefinitionManager.AlterTypeDefinition("Product", cfg => cfg.WithPart("ProductPart"));
return 1;
}
}
On a side note, the naming convention in Orchard is to name the record for a part XXXPartRecord. I don't think your problem lies there though.
I have mentioned this in you other thread.. Orchard Content Type is null
you need
Migrations
public class Migrations : DataMigrationImpl {
public int Create() {
SchemaBuilder.CreateTable("ProductRecord",
table => table
.ContentPartRecord()
.COLUMNS NEED TO BE SPECIFIED
);
ContentDefinitionManager.AlterTypeDefinition("Forum",
cfg => cfg
.WithPart("ProductPart")
.WithPart("CommonPart")
);
Repository
public class ProductPartHandler : ContentHandler {
public ProductPartHandler(IRepository repository) {
Filters.Add(StorageFilter.For(repository));
}
Hope this helps
You could try generating a similar part using the command line utility by pszmyd and see whats different.
http://www.szmyd.com.pl/blog/generating-orchard-content-parts-via-command-line