我決定嘗試創建一個「StringEntity」類來克服這個限制,並使用隱式運算符來輕鬆轉換字符串。請參閱以下解決方案:
public class MyClass
{
[Key, DatabaseGenerated(DatabaseGenerationOption.Identity)]
public Guid Id { get; set; }
public List<StringEntity> Animals { get; set; }
public MyClass()
{
List<StringEntity> Animals = List<StringEntity>();
}
}
public class StringEntity
{
[Key, DatabaseGenerated(DatabaseGenerationOption.Identity)]
public Guid Id { get; set; }
public string Value { get; set; }
public StringEntity(string value) { Value = value; }
public static implicit operator string(StringEntity se) { return se.Value; }
public static implicit operator StringEntity(string value) { return new StringEntity(value); }
}
public class MyDbContext : DbContext
{
public DbSet<MyClass> MyClasses { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<MyClass>()
.HasMany(x => x.Animals)
.WithMany()
.Map(x =>
{
x.MapLeftKey(l => l.Id, "MyClassId");
x.MapRightKey(r => r.Id, "StringEntityId");
});
}
}
...一切看起來很完美,用一些測試(雖然比較重)的工作,然後我在MVC3鑑於實施了其原來的目的,一個多選列表框。由於我未知的原因,如果ListBox被指定了與實體集合屬性相同的名稱,則您的所選項目都不會被加載。
表現出以下不工作: // Razor視圖代碼
string[] animalOptions = new string[] {"Dog", "Cat", "Goat"};
string[] animalSelections = new string[] {"Dog", "Cat"};
Html.ListBox("Animals", Multiselect(animalOptions, animalSelections));
爲了繞過這個限制,我需要做四兩件事:
//#1 Unpluralize the ListBox name so that is doesn't match the name Model.Animals
var animalOptions = new string[] {"Dog", "Cat", "Goat"};
@Html.ListBox("Animal", new MultiSelectList(animalOptions, Model.Animals.Select(x => x.Value)))
//#2 Use JQuery to replace the id and name attribute, so that binding can occur on the form post
<script type="text/javascript">
jQuery(function ($) {
$("select#Animal").attr("name", "Animals").attr("id", "Animals");
});
</script>
//#3 Create a model binder class to handle List<StringEntity> objects
public class StringEntityListBinder : IModelBinder
{
public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
var stringArray = controllerContext.HttpContext.Request.Params.GetValues(bindingContext.ModelName);
return stringArray.Select(x => new StringEntity(x)).ToList();
}
}
//#4 Initialize the binder in your Global.asax setup.
ModelBinders.Binders.Add(typeof(List<StringEntity>), new StringEntityListBinder());
注意,該列表框當屬性是一個字符串列表時,不會發生錯誤,當它是一個實體列表時它不會喜歡它。
您的示例將不起作用。您可以引用LOCAL標量變量的集合,但對於任何給定的實體,您不能引用非實體的集合屬性,即使這只是基元的集合。例如,如果你有p.FavorieColor(字符串),那麼你可以使用「filterBy.Contains(p.FavoriteColor)」,但是你不能迭代集合Property。 – 2011-02-18 19:03:32