Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>A lot of questions in there, and some of the answers might be subjective/opionated, but i'll roll with the punches.</p> <blockquote> <p>IQueryable vs specific methods.</p> </blockquote> <p>I actually agree with you. I don't like the idea of having lots and lots of methods for defining all the different operations on my repository. I prefer to allow the calling code to supply the specification. Now, my calling code is not my presentation - it's a domain service/BLL. So it's not like we're giving full power to the UI, we're just allowing our repository to stay very generic. DDD purists would argue that repositories are abstractions of your domain model, and therefore should serve specific domain operations. I'll leave that open for you to decide. Also, if your using <code>IQueryable</code>, then your forcing an "unknown" LINQ provider to be used. Not a problem for me, as i will always be using something that works off LINQ (Entity Framework, for example). But this is another problem that DDD-purists have.</p> <blockquote> <p>What about when you want to search on first name and last name</p> </blockquote> <p>Well, i use <code>Expression&lt;Func&lt;T,bool&gt;&gt;</code> for my domain services, so i can do this:</p> <pre><code>var customers = repository.FindAll&lt;Customer&gt;(x =&gt; x.FirstName == "Bob" &amp;&amp; x.LastName == "Saget"); </code></pre> <p>If you don't like that, you could use the <strong>Specification</strong> pattern to make use of AND/OR-type code.</p> <blockquote> <p>Deleting customer address</p> </blockquote> <p>Well generally speaking, you should have one repository per aggregate root. Without knowing your domain model, it sounds like "Customer" is an aggregate root, and "CustomerAddress" is an aggregate, which is always associated to a "Customer" (e.g cannot exist without one).</p> <p>Therefore, there you don't require a CustomerAddressRepository. CustomerAddress operations should be done via your CustomerAddress repository.</p> <p>This is why i like to create a <code>GenericRepository&lt;T&gt;</code> implementation of <code>IRepository&lt;T&gt;</code> which implements core operations on the aggregate (Find, Add, Remove), then <em>even more specific</em> implementations deriving from <code>GenericRepository&lt;T&gt;</code>.</p> <p>Here's how i would handle Customer Repository. Create a <code>GenericRepository&lt;T&gt;</code>, which implements <code>IRepository&lt;T&gt;</code> core operations. Then create another interface for <code>ICustomerRepository</code>, which also implements <code>IRepository&lt;T&gt;</code>.</p> <p>Now, create a implementation called <code>CustomerRepository</code>, which inherits the core repository implementation from <code>GenericRepository&lt;T&gt;</code>, and also extends this to allows extra operations (such as removing address).</p> <pre><code>public class CustomerRepository : GenericRepository&lt;Customer&gt;, ICustomerRepository { // inherits, for example: // IQueryable&lt;Customer&gt; Query&lt;Customer&gt;(); public void Remove(Address address) { // get the customer (if you havent already got it) var cust = ctx.Customers.SingleOrDefault(x =&gt; x.CustId == address.CustId); cust.Addresses.Remove(address); } } </code></pre> <p>And your <code>ICustomerRepository</code> would look like this:</p> <pre><code>public interface ICustomerRepository : GenericRepository&lt;Customer&gt;, IRepository&lt;Customer&gt; { // inherited from GenericRepository&lt;Customer&gt; //IQueryable&lt;T&gt; Query&lt;T&gt;(); //void Attach(object entity); //void ForDeletion(object entity); //void SaveChanges(); void Remove(Address address); } </code></pre> <p>Know what i mean? Start with really generic repositories, then get more specific as you require.</p> <p>You do not require a CustomerAddressRepository. Perform the operations via the CustomerRepository as i have shown above.</p> <p>HTH.</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload