NHibernate: Lazy Loading Properties - c#

So, according to Ayende Lazy Loading Properties are already in the NHibernate trunk.
My Problem is: I can't use the trunk for I have FluentNHibernate and LinQ for NHibernate, so I depend on the version they are linked against (Versio 2.x). I can't and don't want to build all the assemblies myself against the newest version of NHibernate.
So, has someone got information about when NHibernate 3.0 will leave Beta-Stadium and the auxiliaries (Linq etc.) will be compiled against it?
I appreciate any estimate!
I need this feature so I can use it on Blob-Fields. I don't want to use workarounds to destroy my object model.

You can compile Fluent with the NH 3.0 binaries, and you don't need L2NH anymore; there's a new integrated provider.

Alternatively it isn't much of a model change. Make a new class, Blob, that has Id, Version and Bytes properties, make a new table to match. Add the new class as a protected property to each of your classes that currently has a blob. Use it like a backing store. Change your mapping to map the underlying property instead of the public one.
public class MyClass
{
public MyClass()
{
MyBlobProperty_Blob= new Blob();
}
public virtual byte[] MyBlobProperty
{
get { return MyBlobProperty_Blob.Bytes; }
}
protected virtual Blob MyBlobProperty_Blob { get; private set; }
}
It is a significant schema change however. This particular solution moves all your binary data into one table.

Related

What is a proper way of writing entity POCO classes in Entity Framework Core?

EF Core has a "code first mentality" by default, i.e. it is supposed to be used in a code-first manner, and even though database-first approach is supported, it is described as nothing more than reverse-engineering the existing database and creating code-first representation of it. What I mean is, the model (POCO classes) created in code "by hand" (code-first), and generated from the database (by Scaffold-DbContext command), should be identical.
Surprisingly, official EF Core docs demonstrate significant differences. Here is an example of creating the model in code: https://ef.readthedocs.io/en/latest/platforms/aspnetcore/new-db.html And here is the example of reverse-engineering it from existing database: https://ef.readthedocs.io/en/latest/platforms/aspnetcore/existing-db.html
This is the entity class in first case:
public class Blog
{
public int BlogId { get; set; }
public string Url { get; set; }
public List<Post> Posts { get; set; }
}
public class Post
{
public int PostId { get; set; }
public string Title { get; set; }
public string Content { get; set; }
public int BlogId { get; set; }
public Blog Blog { get; set; }
}
and this is the entity class in second case:
public partial class Blog
{
public Blog()
{
Post = new HashSet<Post>();
}
public int BlogId { get; set; }
public string Url { get; set; }
public virtual ICollection<Post> Post { get; set; }
}
The first example is a very simple, quite obvious POCO class. It is shown everywhere in the documentation (except for the examples generated from database). The second example though, has some additions:
Class is declared partial (even though there's nowhere to be seen another partial definition of it).
Navigation property is of type ICollection< T >, instead of just List< T >.
Navigation property is initialized to new HashSet< T >() in the constructor. There is no such initialization in code-first example.
Navigation property is declared virtual.
DbSet members in a generated context class are also virtual.
I've tried scaffolding the model from database (latest tooling as of this writing) and it generates entities exactly as shown, so this is not an outdated documentation issue. So the official tooling generates different code, and the official documentation suggests writing different (trivial) code - without partial class, virtual members, construction initialization, etc.
My question is, trying to build the model in code, how should I write my code? I like using ICollection instead of List because it is more generic, but other than that, I'm not sure whether I need to follow docs, or MS tools? Do I need to declare them as virtual? Do I need to initialize them in a constructor? etc...
I know from the old EF times that virtual navigation properties allow lazy loading, but it is not even supported (yet) in EF Core, and I don't know of any other uses. Maybe it affects performance? Maybe tools try to generate future-proof code, so that when lazy-loading will be implemented, the POCO classes and context will be able to support it? If so, can I ditch them as I don't need lazy loading (all data querying is encapsulated in a repo)?
Shortly, please help me understand why is the difference, and which style should I use when building the model in code?
I try to give a short answer to each point you mentioned
partial classes are specially useful for tool-generated code. Suppose you want to implement a model-only derived property. For code first, you would just do it, wherever you want. For database first, the class file will be re-written if you update your model. So if you want to keep your extension code, you want to place it in a different file outside the managed model - this is where partial helps you to extend the class without tweaking the auto-generated code by hand.
ICollection is definitely a suitable choice, even for code first. Your database probably won't support a defined order anyway without a sorting statement.
Constructor initialization is a convenience at least... suppose you have either an empty collection database-wise or you didn't load the property at all. Without the constructor you have to handle null cases explicitely at arbitrary points in code. Whether you should go with List or HashSet is something I can't answer right now.
virtual enables proxy creation for the database entities, which can help with two things: Lazy Loading as you already mentioned and change tracking. A proxy object can track changes to virtual properties immediately with the setter, while normal objects in the context need to be inspected on SaveChanges. In some cases, this might be more efficient (not generally).
virtual IDbSet context entries allow easier design of testing-mockup contexts for unit tests. Other use cases might also exist.

EF7 Proxy Collections Not Generating

I'm trying ASP.NET vNext / Entity Framework 7.
If I have 2 classes: A and B, where one A connects to many "B's," Entity Framework does not generate any proxy collection or proxy class. Thus, when trying to access the collection property, it is always empty unless I add to the collection manually. How does one implement lazy (or even eagerly) loaded collections in EF7?
public class A {
public Guid UniqueId {get;set;}
private ICollection<B> _backing;
public virtual ICollection<B> OneToManyRelationship {
get { return _backing ?? (_backing = new Collection<B>()); }
set { _backing = value; } }
}
public class B {
public A Owner {get;set;}
public string UniqueIdentifier {get;set;}
public int SomeImportantData {get;set;}
}
EF 7 does not support lazy loading upon initial release.
An example of this is lazy loading support, we know this is a critical feature for a number of developers, but at the same time there are many applications that can be developed without this feature. Rather than making everyone wait until it is implemented, we will ship when we have a stable code base and are confident that we have the correct factoring in our core components. To be clear, it's not that we are planning to remove lazy loading support from EF7, just that some apps can start taking advantage of the benefits of EF7 before lazy loading is implemented.
Though I have not yet migrated to EF 7, you should be able to eagerly load your object graph, e.g.
using System.Data.Entity;
...
var query = ctx.A.Include(a => a.OneToManyRelationship);

How to insert an ObservableCollection property to a local sqlite-net db?

I have a quick question about the sqlite-net library which can be found here : https://github.com/praeclarum/sqlite-net.
The thing is I have no idea how collections, and custom objects will be inserted into the database, and how do I convert them back when querying, if needed.
Take this model for example:
[PrimaryKey, AutoIncrement]
public int Id { get; set; }
private string _name; // The name of the subject. i.e "Physics"
private ObservableCollection<Lesson> _lessons;
Preface: I've not used sqlite-net; rather, I spent some time simply reviewing the source code on the github link posted in the question.
From the first page on the sqlite-net github site, there are two bullet points that should help in some high level understanding:
Very simple methods for executing CRUD operations and queries safely (using parameters) and for retrieving the results of those
query in a strongly typed fashion
In other words, sqlite-net will work well with non-complex models; will probably work best with flattened models.
Works with your data model without forcing you to change your classes. (Contains a small reflection-driven ORM layer.)
In other words, sqlite-net will transform/map the result set of the SQL query to your model; again, will probably work best with flattened models.
Looking at the primary source code of SQLite.cs, there is an InsertAll method and a few overloads that will insert a collection.
When querying for data, you should be able to use the Get<T> method and the Table<T> method and there is also an Query<T> method you could take a look at as well. Each should map the results to the type parameter.
Finally, take a look at the examples and tests for a more in-depth look at using the framework.
I've worked quite a bit with SQLite-net in the past few months (including this presentation yesterday)
how collections, and custom objects will be inserted into the database
I think the answer is they won't.
While it is a very capable database and ORM, SQLite-net is targeting lightweight mobile apps. Because of this lightweight focus, the classes used are generally very simple flattened objects like:
public class Course
{
public int CourseId { get; set; }
public string Name { get; set; }
}
public class Lesson
{
public int LessonId { get; set; }
public string Name { get; set; }
public int CourseId { get; set; }
}
If you then need to Join these back together and to handle insertion and deletion of related objects, then that's down to you - the app developer - to handle. There's no auto-tracking of related objects like there is in a larger, more complicated ORM stack.
In practice, I've not found this a problem. I find SQLite-net very useful in my mobile apps.

Lookup tables in Entity Framework 4.1 (the proper way) in C#

With the new release of Entity Framework 4.1, I thought it would be a good time to learn how to utilise it in my coding. I've started off well but I seem to have hit a brick wall and I dont know what the best approach is.
My issue is when using lookup tables, I cant see how to keep my data as objects (rather than lists, anonymous types etc) when pulling in data from a lookup table.
I have looked around on Google but most of the posts I find are prior to the latest release of EF 4.1 and I am assuming that there is a better way to do it.
I have a simple 'invoice header' and 'customer' situation so I have set the mappings up as you would expect (the invoice header has the Id of the customer it relates to).
If I pull in data from only the invoice table then I get a true object that I can bind in to a datagrid and later save changes but this doesnt pull in the customer name like this, for example:
var results = from c in context.InvoiceHeaders
select c;
If I restructure the query to pull back specific columns including drilling down in to the customer table and and getting the customer name directly then I get the data I want but it's now not a type of object that I would expect (invoice object), like this:
var results = from c in context.InvoiceHeaders
select new { c.CreatedBy, c.Customer.Name };
But it now becomes an anonymous type and it seems to lose its bindings back to the database (hope I'm making sense)
So - my question is, "what is the best/official way to use lookup tables in EF 4.1" and/or "can I use lookup tables and keep my bindings"?
Please let me know if you need me to post any code but on this occasion, as it was a general question, I didnt feel I needed to.
Thanks in advance,
James
EF classes are partial so you may expand them :
public partial class InvoiceHeaders
{
public string CustomerName
{
get
{
try
{
return this.Customer.Name;
}
catch
{
return string.Empty;
}
}
private set { }
}
}
But when designing forms, data binding tools does note correctly use this expansion, so you should define a new class and use this class as data source when bind a component to your data source:
public partial class InvoiceHeadersEx : InvoiceHeaders
{
}
and in form.load event change the binding datasource:
private void Form1_Load(object sender, EventArgs e)
{
InvoiceHeadersExDataGridView.DataSource = InvoiceHeadersSource;
InvoiceHeadersBindingSource.DataSource = context.InvoiceHeaders;
}
I think the answer to this is to make sure you're using reference objects (I think that's what EF calls them) in your structure. So that an Invoice doesn't just have public int ClientId {get; set;} but also has public virtual Client Client {get; set;} This gives you a direct link to the actual client- and should still return Invoice objects.
Oh, I get the problem now. When you create an anonymous type, it's basically a new class (it has a type definition and everything). Because it's a new type, which you have control over, it's not an EF data type or linked to a data context.
You're best bet is returning the entire customer object. I appreciate this can cause performance issues when you have large objects, all I can say is, keep your objects smallish.

Save/Load Properties to file or database provider

I need to save and load properties of a Class dynamicly,
but what is the best practis for this ?
I have for now, two classes that I need to save.
public abstract class BaseComponent {
protected int ComponentID { get; set; }
protected string ComponentName { get; set; }
protected Dictionary GetAllProperties{) { /* Reflection */ }
}
public class Article : BaseComponent {
protected string Title { get; set; }
protected string Content { get; set; }
}
Here I'm thinking to table:
Table: Component, ComponentID, Parrent -> and more
Table: ComponentProperties: ComponentID, Key, Value -> and more
I need to use as must of the dotNet framework, but still keep it simpel.
Im think og use a Provider, I need the function og make different data provider:thatcan save to xml file, sql database or oracle database, you name it.
Do I use a provider, or somethnig else ?
The answer for your persistence will depend very much on the scale of what you're writing. Storing XML in files or a database certainly works, as does a metadata driven generic schema (as you described), but making them work for large scale data can be problematic. Salesforce.com did a recent presentation on how they handle dynamic entities in a multi-tenant architecture (see here), but I doubt you need anything of that scale.
My recommendation would be to store as XML to start. The key issues to solve with the generic schema are joins between logical entities and the trouble of pulling together data that belongs to a single entity when it's split out into key/value pairs in a table.
.Net Framework 2.0 or later has a great class that helps you to implement this task, called SettingsBase. You can find it in System.Configuration assembly. You have to create a class for instance BaseComponentSettings and derive it from System.Configuration.SettingsBase. SettingsBase is provider model and you can support many data source as well.

Categories

Resources