If I want to use a Table from a DataContext, I need to instantiate it:
Table<Customer> customers = db.GetTable<Customer>();
But if it's in a custom DataContext:
public partial class Northwind : DataContext
{
public Table<Customer> Customers;
...
}
I can just use it like this:
Table<Customer> customers = db.Customers;
Where is it instantiated?
Based on the documentation, it is just a property getter that return this.GetTable<TEntity>().
Eg.
public partial class DataClasses1DataContext : System.Data.Linq.DataContext {
public System.Data.Linq.Table<User> Users {
get {
return this.GetTable<User>();
}
}
}
Related
I have a collection of Recipes and each one contains Categories. This are my models:
class Recipe extends \Model {
public static $_table = "recipe";
public function categories() {
return $this->has_many_through('Category');
}
}
class Category extends \Model {
public static $_table = "category";
public function categories() {
return $this->has_many_through('Recipe');
}
}
And the table to relate both:
class CategoryRecipe extends \Model {
public static $_table = "category_recipe";
}
Now I need to create a query to get all the Recipes that are under one/more categories. What is the way to achieve this? I want to avoid making things like this:
$results = $app['paris']->getModel('CategoryRecipe')
->where_in("category_id",$selected_categories)
->find_many();
foreach($results as $result) {
$recipe = $app['paris']->getModel('Recipe')
->where('id',$result->recipe_id)
->find_one();
var_dump($receta->name);
}
Create filters? functions inside the models? Is not possible to make it more elegant?
That is pretty much how I would do it, but you can optimise in one way. Add relation functions to your linking/many-to-many table. Then instead of doing that extra query in your foreach loop you simply do:
foreach($results as $result) {
$recipe = $result->recipe()->find_one();
var_dump($recipe)
}
So your CategoryRecipe model might look like:
class CategoryRecipe extends \Model {
public static $_table = "category_recipe";
public function recipe() {
$this->belongs_to('Recipe', 'recipe_id');
}
public function category() {
$this->belongs_to('Category', 'category_id');
}
}
I haven't tested this code, but it should be what you're after I think.
If MVC only allows you to have one ViewModel per View, how does one incorporate a dropdownlist (need to have a separate ViewModel for this) into an existing View which is already used by another ViewModel (ie an entity which has a column for this dropdownlist)?
This Question in addition, I guess, Got everything you are looking for:
How to write a simple Html.DropDownListFor()?
As a beginner, I did a very basic implementation of dropDownlist using the NorthWind Database only.
I had imported the Product & Suppliers table from Northwind database.
In the ProductController.cs file, which is the controller file for my Product table, add method: GetAllSuppliers to get all SuppliersID which we will display in a dropdown.
public IEnumerable<int> GetAllSuppliers()
{
NorthwindEntities db = new NorthwindEntities();
return db.Suppliers.Select(e => e.SupplierID);
}
Now, in the Create action method in ProductController.cs, pass all the values of SupplierID in ViewData as seen below:
public ActionResult Create()
{
ViewData["Suppliers"] = new SelectList(GetAllSuppliers());
return View(new Product());
}
In your corresponding Create.aspx View, use this:
<%: Html.DropDownListFor(model => model.SupplierID, ViewData["Suppliers"] as SelectList) %>
Below is a snapshot of the Result:
Let me know if you need any explanation.
You can make a property inside your main ViewModel which contains ViewModel for dropdownlist and use it with dropdown.
Assume you have controller.
public class HomeController
{
public ActionResult Index()
{
var viewModel = new MainViewModel
{
SomeProperty = "SomeValue",
DropDownData = new DropDownDataViewModel() // Initialize it with appropriate data here.
};
return this.View(viewModel);
}
}
And MainViewModel
public class MainViewModel
{
public string SomeProperty {get; set;}
public DropDownDataViewModel DropDownData { get; set; }
}
So, inside your view you can call #Model.DropDownData to get access to this viewmmodel.
I am having a bit of trouble understanding how I will design a class.
I want to be able to get n amount of System fields out onto a report alongside custom fields.
I want a simple method on an interface called:
ICollection<Field> GetFieldDefinitions();
Internally this should get all the fields that I need to show on the report.
A second method will return field and their values too:
ICollection<Field> GetFieldDefinitionsWithValues(T src);
T is the source of where the information for each field will be populated from, e.g. if I pass in Company, the field definition if it contains CompanyName, I will do a lookup on the Company table and retrieve the info and add it to the field.
public Class SystemFieldCompany
{
IDictionary<string,Field> list;
private readonly ValidationEngine _val;
public SystemFieldCompany(ValidationEngine val)
{
_val = val;
list = new Dictionary<string,Field>();
}
public ICollection<Field> GetFields()
{
list.add("id",new Field{name = "id", value = "5"});
list.add("nameofcompany",new Field{name = "nameofcompany", value = "super guys"});
return list.Values;
}
//pass in model object with values on it, set up fields, then pass back all fields
ICollection<Field> GetFieldsWithValues(T object);
}
Should this class above be a concrete class?
e.g. var fields = new FieldClass().GetFields();
or should I use composition? How can I do this via an interface?
Abstract Class is what your after
public abstract class FieldBase
{
ICollection<Field> _data=new List<Field>();
abstract void DoValidationOrSomething();
ICollection<Field> virtual GetFields() //perform validation internally - return back the object
{
DoValidationOrSomething();
return _data;
}
T virtual UpdateFields(ICollection<Field> fields); //pass in model object with values on it, set
{
_data.Clear();
_data.AddRange(fields);
}
up fields, then pass back all fields
ICollection<Field> virtual GetFieldsWithValues(T object)
{
return _data.Where(f=>f.Name=T);
}
}
then in your concrete
public class SomeTable:FieldBase
{
public void DoValidationOrSomething()
{
//per class validation here
}
}
With the following:
public class AClass
{
public ADependent Dependent { get; set; }
}
public class ADependent
{
public ADependent(AClass ownerValue) {}
}
with the following registrations...
builder.RegisterType<AClass>().PropertiesAutowired().InstancePerDependency();
builder.RegisterType<ADependent>().PropertiesAutowired().InstancePerDependency();
When I resolve an AClass, how do I make sure that 'ownerValue' is the instance of AClass being resolved, and not another instance? Thx
FOLLOW ON
The example above doesn't really catch the problem properly, which is how to wire up ADependent when registering when scanning... for example
public class AClass : IAClass
{
public IADependent Dependent { get; set; }
}
public class ADependent : IADependent
{
public ADependent(IAClass ownerValue) {}
}
// registrations...
builder.RegisterAssemblyTypes(assemblies)
.AssignableTo<IAClass>()
.As<IAClass>()
.InstancePerDependency()
.PropertiesAutowired();
builder.RegisterAssemblyTypes(assemblies)
.AssignableTo<IADependent>()
.As<IADependent>()
.InstancePerDependency()
.PropertiesAutowired();
The function I am looking for really is another relationship type like
public class ADependent : IADependent
{
public ADependent(OwnedBy<IAClass> ownerValue) {}
}
The OwnedBy indicates that ownerValue is the instance that caused ADependent to created. Does something like this make sense? It would certainly make wiring up UI components a breeze.
To extend Steven's approach, you can even Resolve() the second class, passing the first instance as a parameter:
builder.RegisterType<ADependent>();
builder.Register<AClass>(c =>
{
var a = new AClass();
a.Dependent = c.Resolve<ADependent>(TypedParameter.From(a));
return a;
});
You can register a lambda to do the trick:
builder.Register<AClass>(_ =>
{
var a = new AClass();
a.Dependent = new ADependent(a);
return a;
});
I am trying to use Ninject to implement cascading injection into a class that contains an IList field. It seems that, unless I specifically specify each binding to use in the kernel.Get method, the IList property is always injected with a list of a single default object.
The following VSTest code illustrates the problem. The first test fails because the IList field contains one MyType object with Name=null. The second test passes, but I had to specifically tell Ninject what constructor arguments to use. I am using the latest build from the ninject.web.mvc project for MVC 3.
Does Ninject specifically treat IList different, or is there a better way to handle this? Note that this seems to only be a problem when using an IList. Createing a custom collection object that wraps IList works as expected in the first test.
[TestClass()]
public class NinjectTest
{
[TestMethod()]
public void ListTest_Fails_NameNullAndCountIncorrect()
{
var kernel = new Ninject.StandardKernel(new MyNinjectModule());
var target = kernel.Get<MyModel>();
var actual = target.GetList();
// Fails. Returned value is set to a list of a single object equal to default(MyType)
Assert.AreEqual(2, actual.Count());
// Fails because MyType object is initialized with a null "Name" property
Assert.AreEqual("Fred", actual.First().Name);
}
[TestMethod()]
public void ListTest_Passes_SeemsLikeUnnecessaryConfiguration()
{
var kernel = new Ninject.StandardKernel(new MyNinjectModule());
var target = kernel.Get<MyModel>(new ConstructorArgument("myGenericObject", kernel.Get<IGenericObject<MyType>>(new ConstructorArgument("myList", kernel.Get<IList<MyType>>()))));
var actual = target.GetList();
Assert.AreEqual(2, actual.Count());
Assert.AreEqual("Fred", actual.First().Name);
}
}
public class MyNinjectModule : NinjectModule
{
public override void Load()
{
Bind<IList<MyType>>().ToConstant(new List<MyType> { new MyType { Name = "Fred" }, new MyType { Name = "Bob" } });
Bind<IGenericObject<MyType>>().To<StubObject<MyType>>();
}
}
public class MyModel
{
private IGenericObject<MyType> myGenericObject;
public MyModel(IGenericObject<MyType> myGenericObject)
{
this.myGenericObject = myGenericObject;
}
public IEnumerable<MyType> GetList()
{
return myGenericObject.GetList();
}
}
public interface IGenericObject<T>
{
IList<T> GetList();
}
public class StubObject<T> : IGenericObject<T>
{
private IList<T> _myList;
public StubObject(IList<T> myList)
{
_myList = myList;
}
public IList<T> GetList()
{
return _myList;
}
}
public class MyType
{
public String Name { get; set; }
}
lists, collections and arrays are handled slightly different. For those types ninject will inject a list or array containing an instance of all bindings for the generic type. In your case the implementation type is a class which is aoutobound by default. So the list will contain one instance of that class. If you add an interface to that class and use this one the list will be empty.